1

ウィキペディアからの正規の壊れたダブルチェックロックのわずかに変更されたバージョン:

class Foo {
    private Helper helper = null;
    public Helper getHelper() {
        if (helper == null) {
            synchronized(this) {
                if (helper == null) {

                    // Create new Helper instance and store reference on
                    // stack so other threads can't see it.
                    Helper myHelper = new Helper();

                    // Atomically publish this instance.
                    atomicSet(helper, myHelper);
                }
            }
        }
        return helper;
    }
}

基盤となるアトミックopsライブラリが適切に機能していると仮定して、新しく作成されたHelperインスタンスをアトミックに公開するだけで、このダブルチェックのロックイディオムが安全になりますか?Javaでは、を使用するだけでよいことを理解してvolatileいますが、例が疑似Javaであるとしても、これは言語に依存しない質問であると考えられます。

参照:

ダブルチェックロック記事

4

6 に答える 6

14

プラットフォーム/言語の正確なメモリ モデルに完全に依存します。

私の経験則:やらないでください。ロックフリー (またはこの場合は縮小ロック) プログラミングは難しく、スレッドの忍者でない限り、試みるべきではありません。本当に必要であるというプロファイリングの証拠がある場合にのみ、それを熟考する必要があります。その場合、その特定のプラットフォームのスレッドに関する絶対的に最高の最新の本を入手し、それが役立つかどうかを確認してください。

于 2009-02-24T19:21:51.387 に答える
7

コードから完全に離れることなしに、言語にとらわれない方法で質問に答えることはできないと思います。それはすべて、疑似コードでどのようsynchronizedに機能するかによって異なります。atomicSet

于 2009-02-24T19:14:26.207 に答える
2

答えは言語に依存します - それは によって提供される保証に帰着しatomicSet()ます。

myHelper の構築が の後に展開できる場合atomicSet()、変数が共有状態にどのように割り当てられているかは問題ではありません。

すなわち

// Create new Helper instance and store reference on
// stack so other threads can't see it.
Helper myHelper = new Helper(); // ALLOCATE MEMORY HERE BUT DON'T INITIALISE

// Atomically publish this instance.
atomicSet(helper, myHelper); // ATOMICALLY POINT UNINITIALISED MEMORY from helper

// other thread gets run at this time and tries to use helper object 

// AT THE PROGRAMS LEISURE INITIALISE Helper object.

これが言語で許可されている場合、二重チェックは機能しません。

于 2009-02-24T19:23:08.153 に答える
0

volatile を使用しても、複数のインスタンス化を防ぐことはできませんが、同期を使用すると、複数のインスタンスが作成されるのを防ぐことができます。ただし、コードでは、セットアップされる前にヘルパーが返される可能性があります (スレッド 'A' がインスタンス化しますが、セットアップされる前にスレッド 'B' が来ると、ヘルパーは null ではないため、すぐに返されます。修正するにはその問題、最初の if (helper == null) を削除します。

于 2009-02-24T19:22:29.027 に答える
0

部分的に構築されたオブジェクトの問題が解決されていないため、壊れている可能性があります。

于 2009-02-24T19:25:27.150 に答える