以下代码
public class Coordination {
private volatile int counter = 0;
public static void main(String ... args) throws Exception {
new Coordination().volatileWithCoordination();
}
public synchronized void inc() {
counter++;
}
public void volatileWithCoordination() throws Exception {
Thread th1 = new Thread(new Runnable() {
@Override
public void run() {
for(int k = 0; k < 10_000_000; k++) {
synchronized(this) {
//inc();
counter++;
}
}
}});
Thread th2 = new Thread(new Runnable() {
@Override
public void run() {
for(int k = 0; k < 10_000_000; k++) {
//synchronized(this) {
inc();
//counter++;
//}
}
}});
th1.start();
th2.start();
th1.join();
th2.join();
System.out.println("counter: "+counter);
}
}
显示counter: 18025867
的错误且不确定的结果,而切换到:
inc();
//counter++;
第一个线程(th1
)的Runnable中的给出了预期的输出:
counter: 20000000
导致此lost update
行为的原因以及为什么在这种情况下同步方法的行为与同步(此)块的行为不同?
提前谢谢。
答案 0 :(得分:2)
您的线程正在同步不同的对象。您的th2
线程调用同步的inc()
方法,该方法在Coordination
类的实例上进行同步;但当你的th1线程synchronized(this)
时,this
关键字指的是匿名内部Runnable
类的实例,而不是Coordination
类。
答案 1 :(得分:1)
两个线程都需要在同一个对象上获取监视器,以下更改(在2个线程中的任何一个或两者上)修复了这种情况:
synchronized(Coordination.this) {
inc();
//counter++;
}