我正在阅读《Understanding the JVM Advanced Features and Best practice》,其中有一段代码解释了java中的happens-before规则。我无法理解。代码如下:
private int value = 0;
//executed by Thread A
public void setValue(int value){
this.value = value;
}
//executed by Thread B
public void getValue(){
return value;
}
假设线程在代码中的线程A
之前开始。B
我可以理解,我们不知道getValue()
线程 B 中返回的结果,因为它不是线程安全的。setValue()
但是书上说如果在函数和函数中添加同步关键字getValue()
,则不存在线程安全问题,方法getValue()
将返回正确的值。书中解释说,因为synchronized
符合发生前发生的规则。所以我通过下面的代码有两个问题。
public class VolatileDemo3 {
private volatile int value = 0;
public static void main(String[] args) {
VolatileDemo3 v = new VolatileDemo3();
Thread A = new Thread(v.new Test1());// Thread A
Thread B = new Thread(v.new Test2());//Thread B
A.start();
B.start();
}
public void setValue(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
public class Test1 implements Runnable {
@Override
public void run() {
setValue(10);
}
}
public class Test2 implements Runnable {
@Override
public void run() {
int v = getValue();
System.out.println(v);
}
}
}
- 虽然
A.start()
run beforeB.start()
和 value isvolatile
,但我们不能确保线程 B 可以打印出来10
,对吧?因为线程 B 可能首先被 JVM 调度,所以线程 B 将打印 0 而不是 10。 - 即使
A
线程被 JVM 调度在线程之前B
,但我们也不能保证this.value = value
之前被 JVM 执行的指令,return this.value
因为 JVM 会再次对指令进行排序。我的理解是对的吗?请帮我。