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线程