5

このトピックに関する一連の質問/記事を読んだ後、まだ不明なことが1つあります。

私が理解していることから(間違っている場合は修正してください)、変数の値はスレッドにローカルにキャッシュできるため、あるスレッドがその変数の値を更新すると、この変更は別のスレッドには表示されない可能性があります。then を使用するとvolatile、基本的にすべてのスレッドが同じ場所から変数の値を読み取るようになります。さらに、このトピックに関するすべての文献は、その変数で同期すると同じ効果があると述べています。

私の問題は、別の変数で同期すると同じ動作が発生することを明示的に述べているものは何も読んだことがありませんが、次の2つのケースでは変数から読み取られる値が最新であることを示すコード例を頻繁に提供することです. :

volatile int x;
...
int y = x;

final Object lock = new Object();
int x;
...
synchronized(lock) {
    int y = x;
}

質問は次のとおりです。任意の変数で同期すると、同期ブロック内のすべての変数アクセスがその変数の最新の値にアクセスするように強制されるのですか?

4

2 に答える 2

5

任意の変数で同期すると、同期ブロック内のすべての変数アクセスがその変数の最新の値にアクセスするように強制されるのですか?

その変数の書き込みが同じ変数の同期の下で行われた限り、読み取りのために任意の変数を同期できます。

あなたの例では、次のようなことが起こる限り、書き込みの前に発生したすべての書き込みは、x後続の読み取り後に表示されます。

synchronized(lock){
   x = 10;
}

したがって、以前のポイントに:

...私が読んだことのあるものでは、別の変数で同期すると同じ動作が発生することを明示的に述べているものはありません...

これは、同じ動作を提供しないためです。発生前の関係はいくつかの場合に発生します。あなたの場合の2つの重要なものは次のとおりです

  1. 同じ揮発性変数の書き込みとその後の読み取り
  2. 同じオブジェクトに対するモニターの終了とその後の開始
于 2013-09-26T14:16:33.973 に答える
2

それが言及されている啓発的な記事がここにあります:

Java メモリ モデルでは、volatile フィールドには、書き込みの後にストア バリアが挿入され、読み取りの前にロードバリアが挿入されます。...

どのフィールドがアクセスされているかについては何も特定されていないことに注意してください。これは、volatile フィールドにアクセスするとキャッシュされたすべての変数に対してバリアが生成されることを意味します。

同期にも同様の機能があります。

于 2013-09-26T14:31:12.390 に答える