Java の事前発生規則を説明するコード セグメントを含む「JVM の高度な機能とベスト プラクティスについて」を読んでいます。私は理解できない。コードは以下のとおりです。
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
は事前発生規則に適合していると説明しています。したがって、以下のコードで2つの質問があります。
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 は ですが、volatile
スレッド B が を出力できるかどうかは保証できません10
よね? スレッド B は JVM によって最初にスケジュールされる可能性があるため、スレッド B は 10 ではなく 0 を出力します。- JVM によってスレッドの
A
前にスレッドがスケジュールされたとしても、JVM は命令を再度ソートするため、JVMによって以前に実行されB
た命令を保証することはできません。私の理解は正しいですか?私を助けてください。this.value = value
return this.value