饿汉模式
线程安全,调用效率高,但是不能延时加载
public class Singleton1 { private static final Singleton1 instance = new Singleton1(); private Singleton1(){} public static Singleton1 getInstance(){ return instance; } }
懒汉模式
线程不安全,会产生多个实例
public class Singleton2 { private static Singleton2 instance; private Singleton2(){} public static Singleton2 getInstance(){ if (instance == null){ instance = new Singleton2(); } return instance; } }
getInstance()方法加锁(效率低)
public class Singleton3 { private static Singleton3 instance; private Singleton3(){} public synchronized static Singleton3 getInstance(){ if (instance == null){ instance = new Singleton3(); } return instance; } }
双重检测锁模式
由于指令重排序问题,偶尔会出现异常,比如构造方法里面有大量的操作,jvm可能不会等到所有的操作都执行完,才返回实例指针
public class Singleton4 { private static Singleton4 instance; private Singleton4() {} public static Singleton4 getInstance() { if (instance == null) { synchronized (Singleton4.class) { if (instance == null) { instance = new Singleton4(); } } } return instance; } }
5、双重检测锁模式2
通过volatile解决【4】的问题,严格要求happen before,也就是在执行【读】操作的时候必须看到完整的【写】操作
public class Singleton5 { private static volatile Singleton5 instance; private Singleton5() {} public static Singleton5 getInstance() { if (instance == null) { synchronized (Singleton5.class) { if (instance == null) { instance = new Singleton5(); } } } return instance; } }
6、静态内部类
懒加载、线程安全、效率高
public class Singleton6 { private Singleton6() {} private static class InstanceHolder { private static final Singleton6 instance = new Singleton6(); } public static Singleton6 getInstance() { return InstanceHolder.instance; } }
7、枚举
枚举是线程安全的,而且只会被装载一次
public class Singleton7 { private enum Singleton { INSTANCE; private final Singleton7 instance; Singleton() { instance = new Singleton7(); } public Singleton7 getInstance() { return instance; } } public static Singleton7 getInstance(){ return Singleton.INSTANCE.getInstance(); } }