程序修改如下:
class Syn {
private int count = 0;
public void inc() { // 此处不需要同步。
count++;
count++;
System.out.print("+");
count--;
count--;
}
public int getCount() {
return count;
}
}public class SimpleThread extends Thread {
private int no = 0;
private Syn s = null;
private int count = 0;
public SimpleThread(int number, Syn syn) {
no = number;
s = syn;
System.out.println("Making thread" + no);
}
public void run() {
while(true) {
synchronized(s) { // 应该在 s 上同步
s.inc();
if (s.getCount() != 0)
System.out.println("Not equal zero!");
if(count++ > 50) return;
try {
sleep(100);
} catch(Exception e) {}
} // 同步结束
}
}
public static void main(String[] args) {
Syn ss = new Syn();
for (int i = 1; i <= 20; i++)
new SimpleThread(i, ss).start();
System.out.println("All Threads Started");
}
} ///:~
class Syn {
private int count = 0;
public void inc() { // 此处不需要同步。
count++;
count++;
System.out.print("+");
count--;
count--;
}
public int getCount() {
return count;
}
}public class SimpleThread extends Thread {
private int no = 0;
private Syn s = null;
private int count = 0;
public SimpleThread(int number, Syn syn) {
no = number;
s = syn;
System.out.println("Making thread" + no);
}
public void run() {
while(true) {
synchronized(s) { // 应该在 s 上同步
s.inc();
if (s.getCount() != 0)
System.out.println("Not equal zero!");
if(count++ > 50) return;
try {
sleep(100);
} catch(Exception e) {}
} // 同步结束
}
}
public static void main(String[] args) {
Syn ss = new Syn();
for (int i = 1; i <= 20; i++)
new SimpleThread(i, ss).start();
System.out.println("All Threads Started");
}
} ///:~
谢谢!改成这样结果正确了。但我不大明白为什么我那样用synchronized方法就不行?而在这台p233机器上就可以。能否解答一下。非常感谢。
相反,我觉得后者的写法是错误的.
再回答一下biti_9512207,你说前半部分也对,只不过是和我说的方法写法不同。如果一个类实例所有的方法都是同步方法,当然在访问这个类的时候自然要获得这个实例的锁,不过如果这个类的某个方法其实不需要上锁的话就浪费效率了。而在使用到这个类的时候显示获取锁的话(象我写法一样),就不需要在无需付出上锁的代价的时候去上锁了。
简单一点说:我的方法是在需要时显示要求实例锁,你的方法是只要用到这个类的时候都隐式要求上锁。如果顶楼的这个程序中,这两种方法都是效果一样的。
不过我的程序还有一点可以改进:
synchronized(s) { // 应该在 s 上同步
s.inc();
if (s.getCount() != 0)
System.out.println("Not equal zero!");
} // 同步结束 if(count++ > 50) return;
try {
sleep(100);
} catch(Exception e) {}
同步块应尽快结束更好。
sleep((long)(100*Math.random()));
后发现在p233上也有不同步了。
luodi的方法很好。二位使我对同步的理解更深了一些。再次感谢!