コードが while ループから抜けることが保証されていますか?
いいえ。Java メモリ モデルは、「発生前」の関係で定義されています。
2 つのアクションは、先行発生関係によって順序付けできます。あるアクションが別のアクションの前に発生する場合、最初のアクションは 2 番目のアクションよりも前に表示され、順序付けされます。
仕様は次のように続けています。
アクション x が後続のアクション y と同期する場合、hb(x, y) も得られます。
wherehbは、事前発生を表し、
モニター m のロック解除アクションは、m の後続のすべてのロック アクションと同期します (「後続」は同期順序に従って定義されます)。
また、次の点にも注意してください。
hb(x, y) と hb(y, z) の場合、hb(x, z) です。
したがって、あなたの例では、synchronized(lock)aroundbは次の読み取りの事前発生関係を確立するため、 の値はb、 も使用する他のスレッドで表示されることが保証されますsynchronized(lock)。明示的に、
hb(write to b in threadOne, unlock in threadOne) AND
hb(unlock in threadOne, lock in threadTwo) AND
hb(lock in threadTwo, read from a in threadTwo) IMPLIES
hb(write to b in threadOne, read from b in threadTwo)
同様にa、他のスレッドから見えることが保証されます。明示的に、
hb(write to a in threadOne, lock in threadOne) AND
hb(lock in threadOne, unlock in threadOne) AND
hb(unlock in threadOne, lock in threadTwo) AND
hb(lock in threadTwo, read a in threadTwo) IMPLIES
hb(write to a in threadOne, read a in threadTwo).
の書き込みとそれに続く読み取りにcは、事前発生の関係がないため、仕様によると、 への書き込みcが必ずしも に表示されるとは限りませんthreadTwo。
式から変数 c を削除するとどうなるでしょうか。同期ブロック内にあったため、b のみが threadTwo で表示されることが保証されているかどうか疑問に思っています。
はい、上記を参照してください。