3

静的初期化を使用してスレッドセーフなシングルトンを実装する場合、Initialize-On-Demand イディオムは本当に必要ですか、それともインスタンスの単純な静的宣言で十分でしょうか?

静的フィールドとしてのインスタンスの簡単な宣言:

class Singleton
{
 private static Singleton instance=new Singleton();

 private Singleton () {..}
 public static Singleton getInstance()
 {
  return instance;
 }
}

class Singleton {
   static class SingletonHolder {
      static final Singleton INSTANCE = new Singleton();
   }

   private Singleton () {..}

   public static Singleton getInstance() {
      return SingletonHolder.INSTANCE;
   }
}

Brian Goetz がこの記事で最初のアプローチを推奨しているため、私はこれを尋ねます。

http://www.ibm.com/developerworks/java/library/j-dcl/index.html

この記事では後者を提案していますが、

http://www.ibm.com/developerworks/library/j-jtp03304/

後者のアプローチには、前者にはない利点がありますか?

4

3 に答える 3

3

私が言えることは、これらの記事は 7 ~ 9 年前のものです。

現在、Java 1.5 があり、列挙の力がありますenum。「Josh Block」によると、シングルトンを作成する最良の方法は、単一要素列挙型を作成することです

public enum MySingleton{
    Singleton;

    // rest of the implementation.
    // ....
}

しかし、あなたの質問については、どちらの実装を使用しても問題はないと思います。私は個人的に最初のオプションを好みます。なぜなら、それは簡単で理解しやすいからです。

ただし、オブジェクトをシリアライズおよびデシリアライズするか、オブジェクトのクローンを作成することにより、同じ JVM でこれらのクラスのオブジェクトを同時に作成できる抜け穴に注意してください。

また、クラスを拡張することでシングルトンに違反する可能性があるため、クラスを final にします。

于 2011-07-25T06:38:47.807 に答える
3

Singleton最初のアプローチでは、クラスをロードするとシングルトンが作成されます。もう1つは、メソッドを呼び出すと作成されますgetInstance()Singletonクラスには、呼び出す前にロードする多くの理由がある場合がありますgetInstance。そのため、実際に使用するときにかなり早く初期化する可能性が高く、遅延初期化の目的が無効になります。遅延初期化が必要かどうかは別の話です。

于 2011-07-25T06:42:00.203 に答える
2

単純な宣言パターンは、クラス Singleton がロードされたときにシングルトンを構築します。オンデマンド初期化イディオムは、Singeton.getInstance() が呼び出されたとき、つまりクラス SingetonHolder がロードされたときにシングルトンを構築します。

したがって、これらは時間を除いて同じです。2 番目のオプションでは、初期化を遅らせることができます。いつどちらを選択するかは、Singleton のコンストラクターでどれだけの作業を行っているかによって異なります。数が多い場合は、初期化オンデマンドでアプリケーションの起動時間が改善されることがあります。

そうは言っても、私のアドバイスは、最も単純なパターンが機能するように、そこでやりすぎないようにすることです.

-dg

于 2011-07-25T06:57:11.540 に答える