James GoslingのJLSを読んでいて、これに出くわしました-
Java プログラミング言語は、いくつかの目的でロックするよりも便利な、 (同期以外の)揮発性フィールドという2 番目のメカニズムを提供します。
フィールドはvolatileと宣言される場合があります。この場合、Java メモリ モデルは、すべてのスレッドが変数の一貫した値を参照することを保証します。次に、作成者はこのリソースを指します。
その結果r2 == 2
、r1 == 1
不可能に見えるかもしれません。
しかし、なぜ?
このようなことを考えるのは完全に理にかなっているではありませんか-
Instruction 4 : A = 2;
Instruction 1 : r2 = A;
Instruction 2 : B = 1;
Instruction 3 : r1 = B;
そして残りは私も理解できませんでした。
r2 == 2 と r1 == 1 という結果はありえないように見えるかもしれません。直感的には、命令 1 または命令 3 のいずれかが最初に実行されます。命令 1 が最初に来る場合、命令 4 の書き込みを認識できないはずです。命令 3 が最初に来る場合、命令 2 の書き込みを認識できないはずです。
何らかの実行がこの動作を示した場合、命令 4 が命令 1 の前に発生し、命令 2 が命令 2 の前に発生し、命令 3 が命令 4 の前に発生したことがわかります。これは一見、ばかげています。
ただし、コンパイラは、どちらかのスレッドの命令を並べ替えることができますが、これがそのスレッドの実行に単独で影響を与えない場合です。表 17.4-B のトレースに示すように、命令 1 が命令 2 で並べ替えられた場合、結果 r2 == 2 および r1 == 1 がどのように発生するかを簡単に確認できます。
例えてください。