0

他のスレッドがこのメンバー変数にアクセスする前に、1 つのスレッドを介してvolatile staticメンバー変数で動作する一連のメソッドが実行されることを保証する方法はありますか? 私はこのようなことを試みていますが、うまくいくかどうかはわかりません。

public class MyClass
{
  private static final Object lock = new Object();
  public static volatile MyObj mo; //assume null will be checked before access

  public static void initialize()
  {
    if (mo == null)
    {
      synchronized(lock)
      {
        mo = new MyObj();
        mo.doInit();
        mo.doMoreInit();
      }
    }
  }
}
4

3 に答える 3

1

moすべてのメソッドが呼び出されるまでの割り当てを遅らせる必要があります(つまり、ローカル変数を使用してから、最後のmoステップとして割り当てます)。

基本的に二重チェックロックを実装していることに注意してください(ただし、揮発性を使用すると「正しく」機能します)。同期ブロック 内でmo再度 nullをチェックする必要があります。

また、同期を管理するためにクラス初期化パターンを使用するなど、これにはいくつかの他の (やや優れた) パターンがあります。考えられるほぼすべてのパターンがここで詳しく説明されていますhttp://en.wikipedia.org/wiki/Singleton_pattern

于 2013-08-21T12:56:15.787 に答える
1

二重チェックのロックイディオムを使用して、シングルトンパターンを探しています:

private static volatile MyObj obj = null;

public static MyObj getObj() {
    if (obj == null) {
        synchronized (MyClass.class) {
            if (obj == null) {
                obj = new MyObj();
            }
        }
    }
    return obj;
}

フィールドは非公開であり、getObj()メソッドを介して (このメソッドを介してのみ) アクセスされることに注意してください。フィールドが public の場合、任意のスレッドがいつでもアクセスできます。メソッドの背後にあるアクセスをカプセル化せずに、フィールドへのアクセスを同期することはできません。

この保証を得るためのより簡単な方法がありますが、遅延初期化が必要な場合は、すべて、知る限り、メソッドを呼び出す必要があります。

于 2013-08-21T13:00:01.953 に答える
0

ゲッターを設定し、メソッドが実行されることを確認するためにチェックするいくつかのフラグを持つことができます。ゲッターは、実行が完了するのを待って、必要なメソッド自体を起動することができます。

于 2013-08-21T12:55:01.463 に答える