單例模式的3種實現方式, 及其性能對比

1. 懶漢模式(double check), 線程安全, 效率不高, 能夠延遲加載java

 public class Singleton1 implements Serializable {
 // 用volatile修飾instance, 禁止指令重排序, 爲保證多線程安全
 private volatile static Singleton1 instance = null;
 private Singleton1() {
  // 防止反射調用私有構造方法(跳過安全檢查), 重複實例化實例
  if (instance != null) {
   throw new RuntimeException("error:instance=" + instance);
  }
 }
 public static Singleton1 getInstance() {
  if (instance == null) {
   synchronized (Singleton1.class) {
    if (instance == null) {
     instance = new Singleton1();
    }
   }
  }
  return instance;
 }
 private Object readResolve() {
  return instance;    // 防止反序列化重複實例化實例
 }
}

2. 餓漢模式, 線程安全, 效率高, 可是不能延遲加載web

 public class Singleton2 implements Serializable {
 private static Singleton2 instance = new Singleton2();
 private Singleton2() {
  // 防止反射調用私有構造方法(跳過安全檢查),重複實例化實例
  if (instance != null) {
   throw new RuntimeException("error:instance isn't null " + instance);
  }
 }
 public static Singleton2 getInstance() {
  return instance;
 }
 private Object readResolve() {
  return instance;    // 防止反序列化重複實例化實例
 }
}

3. 私有靜態內部類, 線程安全, 調用效率高, 能夠延遲加載安全

public class Singleton3 {
 private Singleton3() {
 }
 private static class Singleton0 {
  private static final Singleton3 instance = new Singleton3();
 }
 /*
  * 獲取私有靜態內部類中的實例對象
  */
 public static Singleton3 getInstance() {
  return Singleton0.instance;
 }
}

3種方式的性能分析:多線程

public static void main(String[] args) throws Exception {
  long start = System.currentTimeMillis();
  int countNum = 1000;
  final CountDownLatch count = new CountDownLatch(countNum);
  for (int i = 0; i < countNum; i++) {
   new Thread(new Runnable() {
    @Override
    public void run() {
     for (int i = 0; i < 1000000; i++) {
      // Singleton1.getInstance();    // 懶漢模式(double check)
      // Singleton2.getInstance();    //餓漢模式
      Singleton3.getInstance();    // 私有靜態內部類
     }
     count.countDown();
    }
   }).start();
  }
  count.await();
  long end = System.currentTimeMillis();
  System.out.println(end - start);
 }

Console輸出:ide

懶漢模式(double check): 310ms性能

餓漢模式: 150msspa

私有靜態內部類: 160ms線程

相關文章
相關標籤/搜索