2

Joshua Bloch による「Effective Java Second Edition」を読んでいて、同時実行性に関する以下のステートメントに混乱しています -

「言語仕様では、変数が long または double 型でない限り、変数の読み取りまたは書き込みがアトミックであることを保証しています [JLS、14.4.7]。つまり、long または double 以外の変数の読み取りは、次の値を返すことが保証されています。複数のスレッドが同期せずに同時に変数を変更したとしても、何らかのスレッドによってその変数に格納されました。」

これは、誰かが手元に本を持っている場合に備えて、259 ページの最後の段落に記載されています。

複数のスレッドが変数を変更している場合でも、参照される変数は常に値を持つとは限りませんか?

4

3 に答える 3

4

文全体を読む必要があります。ここで、あなたのためにそれを言い換えましょう:

「つまり、long または double 以外の変数を読み取ると、複数のスレッドが同時に変数を同期せずに変更したとしても、あるスレッドによってその変数に格納された値を返すことが保証されます。」

になります:

「変数が long または double ではないと仮定しましょう (特別なルールが適用されるため)。変数を保護するために同期せずに同時に変数を変更する複数のスレッドがある場合でも、変数には常に値があります。

この値は常に、スレッドの 1 つが書き込んだ値の 1 つです。事前にどれがどれかを知ることはできませんが、常にそれらのいずれかが書き込んだ値になります。中途半端な値になることはありません。」

于 2011-12-01T00:14:59.700 に答える
1

volatileキーワードが追加されていない double または long との間で書き込みおよび読み取りを行う複数のスレッドがある場合。読み取りによって、以前に書き込まれたことのない値が取得される可能性があります。

この理由は、これらが4 バイト長ではなく 8 バイト長であるため、変数の新しい値の半分と古い値の残りの半分を読み取ることができるからです (特定のアーキテクチャに基づいてこれほど単純ではないかもしれませんが、これが考え方です)。 )、書き込まれたことのない誤った読み取りが発生します。

于 2011-12-01T00:07:07.267 に答える
0

彼は、変数には値があると言っていますが、その値は非決定論的です (変数に対する同時スレッドのアクションのため)。

于 2011-12-01T00:05:09.560 に答える