2

(ウィキペディアより)

//遅延初期化:

public class Singleton {

    private static volatile Singleton instance = null;

    private Singleton() {   }

    public static Singleton getInstance() {
            if (instance == null) {
                    synchronized (Singleton.class){
                            if (instance == null) {
                                    instance = new Singleton();
                            }
                  }
            }
            return instance;
    }
}

//熱心な初期化:

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

   private Singleton() {}

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

「プログラムがクラスを使用しているが、おそらくシングルトン インスタンス自体を使用していない場合は、遅延初期化に切り替えることをお勧めします。」

1 - わかったかどうかわからない。プログラムでクラスを使用してはいけないのはなぜですか? 属性/メソッドを追加するだけでは解決できないのはなぜですか? それに関して、定数参照はどのように変更する必要がありますか?

2 - 遅延初期化 - コード ブロックではなく getInstance() を同期する (ダブル チェックを取り除く) と、マルチスレッドが発生すると、プログラムにどのような影響がありますか?

ありがとうございました。

4

4 に答える 4

4

1 - アプリケーションにはさまざまな jar が含まれる場合がありますが、必ずしも各 jar 内のすべての機能を使用するとは限りません。さらに、アプリケーションのユーザーは、アプリケーションに組み込まれたすべての機能を使用するわけではありません。たとえば ReportABug クラスがある場合、あなたは素晴らしいプログラマーなので、メニューからその機能をアクティブにすることは決してないかもしれません ;-)

静的フィールド/メソッドは、クラスが実行時に必要になるまでインスタンス化/呼び出されないため、ReportABug クラスには数千の静的フィールドが含まれる可能性がありますが、クラスがロードされないため、メモリを消費することはありません。

彼らの要点は、シングルトン(または複数)を持つクラスには、シングルトンにアクセスしない他の静的メソッドがある可能性があるということです。

2 - シングルトン クラス オブジェクトに対してメソッドを同期することはできますが、getInstance を呼び出すたびにオーバーヘッドが発生します。インスタンス == null (1 マシン サイクル) かどうかをチェックするだけの方がはるかに安価です。外側の ==null チェックの後に別のスレッドがスレッドを横取りしてインスタンスを作成する可能性があるため、両方のテストが必要です。

于 2012-08-12T12:00:45.937 に答える
2
  1. 常にすべてのクラスを使用するとは限りません。おそらく、プログラム内の一部のパスでインスタンスが使用され、一部のパスではインスタンスが使用されません。
  2. ブロックの代わりにメソッドを同期すると、誰かが参照を必要とするたびにロックを取得する必要があります。これは非常に無駄です。synchronizedロックの競合を最小限に抑えるために、常にブロックをできるだけ小さく保つ必要があります。
于 2012-08-12T11:50:17.630 に答える
0

1-Javaには多くのクラスがあり、常にすべてを使用するとは限りません。熱心な初期化を使用してシングエルトン クラスを定義し、このクラスが必要ない場合、メモリを浪費することになります。

于 2012-08-12T11:47:06.207 に答える