0

いくつかの記事では、volatile を使用すると Double Checked Locking の問題が修正されると書かれています。

class Foo {
        private volatile Helper helper = null;
        public Helper getHelper() {
            if (helper == null) {
                synchronized(this) {
                    if (helper == null)
                        helper = new Helper(); //Important
                }
            }
            return helper;
        }
    }

しかし、ここでヘルパー フィールドに volatile を使用したとしても、これを安全なパブリケーションにするにはどうすればよいでしょうか。つまり、一貫性のないヘルパー オブジェクトを取得しないことをどのように保証できるのでしょうか?

4

4 に答える 4

1

JVMがの順序を保持しているためだと思いますhelper=new Helper()。つまり、オブジェクトの作成後にのみ割り当てが行われます。私が間違っている場合は、私を修正してください。

于 2013-01-27T09:52:36.657 に答える
0

高レベルの観点から、は、 volatilevolatile 書き込みの前に発生したアクション (つまり、内部のアクション) の結果が、後続の volatile 読み取り (つまり、別のスレッドが外部チェックを参照したとき)new Helper()の後に、他のスレッドから見えることを保証します。helper != null

低レベルの観点からは、実装に依存します。しかし、一般的に:

  • 以前のアクションで揮発性書き込みの並べ替えを引き起こす可能性のあるコンパイラの最適化は禁止する必要があります
  • JIT は生成されたコードにメモリ バリアを挿入して、CPU レベルでの同様の並べ替えを防止する必要があります (特定の CPU アーキテクチャでそのような並べ替えが許可されている場合)。
于 2013-01-27T10:12:51.020 に答える