シングルモード

2225 ワード

本文は主に単例モードの1種の書き方、注意事項、作用、テストを紹介して、Java言語を例にして、以下のコードは現在見た中で最も良い書き方です:
public class Singleton {
 
    private static volatile Singleton instance = null;
 
    // private constructor suppresses
    private Singleton(){
    }
 
    public static Singleton getInstance() {
        // if already inited, no need to get lock everytime
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
 
        return instance;
    }
}

1、注意すべき点注意すべき点は主に3点(1)私有化コンストラクタ(2)静的Singleton instanceオブジェクトを定義することとgetInstance()メソッド(3)getInstance()メソッドで同期ロックsynchronized(Singleton.class)を使用してマルチスレッドが同時に進入することを防止することでinstanceが複数回インスタンス化されていることから、synchronized(Singleton.class)の外にifが追加されていることがわかります.これは、instanceがインスタンス化された後、synchronized(Singleton.class)を実行せずにオブジェクトロックを取得し、パフォーマンスを向上させるためです.
Ps:private static Object obj=new Object()を使用する実装もあります.synchronized(obj)を加えると、実際にオブジェクトを複数作成する必要はありません.synchronized(X.class) is used to make sure that there is exactly one Thread in the block.
2、単例の作用単例は主に2つの作用がある(1)プログラムの実行中にこのクラスは常に1つの例しか存在しない(2)new性能の消耗が大きいクラスに対して、一度だけインスタンス化すれば性能を向上させることができる
3、単例モードテスト単例モードはマルチスレッドを使用して同時にテストすることができ、コードは以下の通りである.
public static void main(String[] args) {
    final CountDownLatch latch = new CountDownLatch(1);
    int threadCount = 1000;
 
    for (int i = 0; i < threadCount; i++) {
        new Thread() {
 
            @Override
            public void run() {
                try {
                    // all thread to wait
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } 
                // test get instance
                System.out.println(Singleton.getInstance().hashCode());
            }
        }.start();
    } 
    // release lock, let all thread excute Singleton.getInstance() at the same time
    latch.countDown();
}

ここでCountDownLatch latchは閉鎖であり、すべてのスレッドでlatchが使用する.await();ロックの解放を待つ、すべてのスレッドの初期化が完了するまでlatchを使用する.countDown();ロックを解除する、スレッドに到達してSingletonを同時に実行する.getInstance()の効果.