Java 中的同步块与同步方法限定符
Synchronized block vs. synchronized method qualifier in Java
下面的代码
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
行为?为什么在这种情况下同步方法的行为与同步(this)块不同?
提前致谢。
两个线程都需要在同一个对象上获取监视器,以下更改(在两个线程中的一个或两个线程上)修复了这种情况:
synchronized(Coordination.this) {
inc();
//counter++;
}
您的线程正在不同的对象上同步。您的 th2
线程调用同步 inc()
方法,该方法在 Coordination
class 的实例上同步;但是当你的 th1 线程执行 synchronized(this)
时,this
关键字引用匿名内部 Runnable
class 的实例,而不是 Coordination
class.
下面的代码
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
行为?为什么在这种情况下同步方法的行为与同步(this)块不同?
提前致谢。
两个线程都需要在同一个对象上获取监视器,以下更改(在两个线程中的一个或两个线程上)修复了这种情况:
synchronized(Coordination.this) {
inc();
//counter++;
}
您的线程正在不同的对象上同步。您的 th2
线程调用同步 inc()
方法,该方法在 Coordination
class 的实例上同步;但是当你的 th1 线程执行 synchronized(this)
时,this
关键字引用匿名内部 Runnable
class 的实例,而不是 Coordination
class.