9

このコードで volatile と synchronized を一緒に使用する理由はありますか?

public class Helper {
  private volatile int n;
  private final Object lock = new Object();
  public Helper(int n) {
    this.n = n;
  }

  public void setN(int value) {
    synchronized (lock) {
      n = value;
    }
  }
}

クラス ヘルパーはスレッド セーフである必要があります。「Java Concurrency Guidelines」の本からこの例を入手しましたが、まだ明確ではありません。この例で volatile と synchronized を一緒に使用する理由は何ですか?

4

3 に答える 3

7

この例の目的は、オブジェクトが危険な状態で公開される可能性があるという事実 (つまりinなし)を考えると、この場合、syncronizedなしvolatileでは不十分であることを指摘することです。volatileFoo

Foo クラスのヘルパー フィールドが volatile と宣言されていない場合は、n フィールドを volatile と宣言して、n の初期化と Helper のヘルパー フィールドへの書き込みとの間に先行発生関係が確立されるようにする必要があります。ガイドライン「VNA06-J. オブジェクト参照を volatile と宣言することで、そのメンバーの可視性が保証されると想定しないでください」(35 ページ)。

それは正しいのですがvolatile、この場合は同期がなくても十分であるため、彼らはそれを実証するために悪い例を選びました。

于 2012-04-12T12:07:44.747 に答える
1

値の変化の周りに同期ブロックを配置する必要はありません。Java 5 以降、これは揮発性変数に対して「自動的に」行われます。Java 5 より前は、必ずしもそうではなかったと思います。

于 2012-04-12T11:52:58.107 に答える
0

コンストラクターに「n」が設定されているため、揮発性が使用されていると思います

于 2012-04-12T11:51:21.047 に答える