Red > Green > Refactor > Red

cycle is based on desire

Singleton pattern

(Java の深み)

インスタンス生成は一回だけ

src
  |
  +-- jp.ymatsukawa
      +-- Main.java
      |
      +-- single
           |
           + -- Single.java

jp.ymatsukawa/Main.java

package jp.ymatsukawa;

import jp.ymatsukawa.single.Single;

public class Main {
  public static void main(String[] args) {
    Single singleFirst  = Single.getInstance();
    Single singleSecond = Single.getInstance();
    if(singleFirst == singleSecond) {
      System.out.println("objective ref equiv");
    }
  }
}

System out

objective ref equiv

jp.ymatsukawa/single/Single.java

Bill Pugh Singleton Implementation

  • (要検証)
    • スレッドセーフ, かつパフォーマンス落ちを懸念しなくて良い
      • getInstance が呼ばれた時
      • Single class が ClassLoad される
      • マルチスレッドで重複して SingleClass が ClassLoad された時
      • 2 回目以降の ClassLoad は 1 回目の ClassLoad を待つ
package jp.ymatsukawa.single;

public class Single {
  private Single() {}
  private static class SingletonHelper {
    private static final Single INSTANCE = new Single();
  }
  public static Single getInstance() {
    return SingletonHelper.INSTANCE;
  }
}

stackoverflow.com

Lazy Initialization

  • シングルスレッド向き
  • (未検証)
    • マルチスレッド構築時には、インスタンスの重複生成が起こりうる脆弱な設計
    • 「instance == null」時にスレッドが重複して if 句を実行する
    • → スレッド毎のインスタンスが生成され、シングルトンが実現できない
package jp.ymatsukawa.single;

public class Single {
  private static Single singleInstance;
  private Single() {}
  public static Single getInstance() {
    if(singleInstance == null) {
      singleInstance = new Single();
    }
    return singleInstance;
  }
}

Thread Safe Singleton

jp.ymatsukawa/single/Single.java

package jp.ymatsukawa.single;

public class Single {
  private static Single singleInstance;
  private Single() {}
  public static synchronized Single getInstance() {
    if(singleInstance == null) {
      singleInstance = new Single();
    }
    return singleInstance;
  }
}

technical reference

www.journaldev.com

stackoverflow.com