sun*_*nny 5 java multithreading happens-before
我正在阅读"了解JVM高级功能和最佳实践",其中包含一个代码段,用于解释java中的先发制人规则.我不明白.代码如下:
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;
}
Run Code Online (Sandbox Code Playgroud)
假设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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
A.start()之前运行B.start()和值是volatile,我们无法确保线程B可以打印出来10,对吧?因为线程B可能首先由JVM调度,所以线程B将打印0而不是10.A线程B由JVM 调度之前的线程,但我们也无法保证this.value = valueJVM之前执行的指令return this.value因为JVM会再次排序指令.我的理解是对的吗?请帮我."之前发生"的问题不是它导致线程A在线程B之前设置值.虽然可能发生线程A this.value = value在线程B运行之前按时间顺序到达getValue,但是B看到的值仍然可能是旧的价值.
也就是说,在线程环境中,即使按时间顺序执行两个指令,也不意味着一个指令的结果将被另一个指示.
如果线程B碰巧首先调用该方法,它将始终获得旧值.但是,如果碰巧将方法称为第二个,那么它是否会获得旧值或新值是未知的.
出于这个原因,你必须使用手段来确保"之前发生"规则,然后你知道"之前发生的事情"的结果可以通过"发生之后"看到.
因此,如果value是volatile,例如,它确保setValue()在线程B之前由线程A调用if ,则线程B将看到新值.
?????????????????????????????????????????????????????????????????????? ? Order of operations ? Are we using ? What value of value ? ? ? volatile/synchronized? ? will B see? ? ?????????????????????????????????????????????????????????????????????? ? A runs setValue(10) ? N ? Unknown ? ? B runs getValue() ???????????????????????????????????????????????? ? ? Y ? 10 ? ?????????????????????????????????????????????????????????????????????? ? B runs getValue() ? N ? 0 ? ? A runs setValue(10) ???????????????????????????????????????????????? ? ? Y ? 0 ? ??????????????????????????????????????????????????????????????????????
关于你的两个问题: