コードが 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 で表示されることが保証されているかどうか疑問に思っています。
はい、上記を参照してください。