单例模式的3种实现方式, 及其性能对比

余生长醉 提交于 2020-02-29 01:26:38

1. 懒汉模式(double check), 线程安全, 效率不高, 可以延迟加载

 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. 饿汉模式, 线程安全, 效率高, 但是不能延迟加载

 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输出:

懒汉模式(double check): 310ms

饿汉模式: 150ms

私有静态内部类: 160ms

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!