15

以下はクラシックからのものですConcurency in Practice

スレッド A が揮発性変数に書き込み、続いてスレッド B が同じ変数を読み取ると、揮発性変数に書き込む前に A に表示されていたすべての変数の値が、揮発性変数の読み取り後に B に表示されます。

私はこの声明を本当に理解できるかどうか確信が持てません。たとえば、この文脈におけるすべての変数の意味は何ですか? これはvolatile、非揮発性変数の使用にも副作用があるということですか?
この声明には、私には理解できない微妙な意味があるように思えます。
何か助けはありますか?

4

2 に答える 2

14

あなたの質問への答えはJLS #17.4.5にあります:

揮発性フィールド (§8.3.1.4) への書き込みは、そのフィールドの後続のすべての読み取りの前に発生します。

したがって、1つのスレッドにある場合

aNonVolatileVariable = 2 //w1
aVolatileVariable = 5 //w2

その後、別のスレッドで:

someVariable = aVolatileVariable //r1
anotherOne = aNonVolatileVariable //r2

anotherOneその変数が揮発性でない場合でも、2 に等しいことが保証されます。そうです、volatile を使用すると、非 volatile 変数の使用にも副作用があります。

より詳細には、これは同じセクションで Java メモリ モデル (JMM) によって提供される他の 2 つの保証によるものです: スレッド内順序と推移性 ( hb(x,y)x が y の前に発生することを意味します):

x と y が同じスレッドのアクションであり、プログラムの順序で x が y の前にある場合、hb(x, y) .
[...]
hb (x, y)hb(y, z)の場合、hb(x, z) .

私の例では:

  • hb(w1, w2)およびhb(r1, r2) (スレッド内セマンティクス)
  • hb(w2, r1) volatile 保証のため

したがって、推移性によってhb(w1, r2)と結論付けることができます。

また、JMM は、プログラムが事前発生関係と正しく同期されている場合、プログラムのすべての実行が順次一貫している (つまり、何も並べ替えられていないように見える) ことを保証します。したがって、この特定のケースでは、不揮発性読み取りは、不揮発性書き込みの効果を見ることが保証されています。

于 2012-09-16T10:26:09.297 に答える
9

これは、10 個の不揮発性変数に書き込み、揮発性変数に書き込む場合、すべての不揮発性変数を揮発性変数の前に設定する必要があることを意味します。

揮発性変数とすべての非揮発性変数を読み取れば、順序が入れ替わらないことを確認できます。

于 2012-09-15T15:08:14.040 に答える