1.恶汉式:静态常量
单例的实例被声明称static和final,在类加载到内存的就是就被初始化了,同时也是线程安全的
public class Singleton1 { private final static Singleton1 instance = new Singleton1(); private Singleton1(){} public static Singleton1 getInstance(){ return instance; }
缺点:不是懒加载,单例会在类加载后就会被初始化,即使没有调用getInstance方法。在一些场景中将无法使用:比如Singleton实例的创建是依赖参数或者配置文件的,在getInstance()之前必须调用某个方法设置参数给它,那么单例写法就无法使用了。
2.懒汉式:线程不安全
public class Singleton2 { private static Singleton2 instance ; private Singleton2(){} public static Singleton2 getInstance(){ if(instance == null){ instance = new Singleton2(); } return instance; } }
缺点:多线程并行调用getInstance的时候不能正常工作(存在线程安全问题)
3.懒汉式:线程安全
public class Singleton4 {
private static Singleton4 instance;
private Singleton4(){}
public static synchronized Singleton4 getInstance(){
if(instance == null){
instance = new Singleton4();
}
return instance;
}
--虽然做到了线程安全,但是并不高效。
4.懒汉式:静态内部类(推荐)
public class Singleton5 { private static class SingletonHandler{ private static final Singleton5 INSTANCE = new Singleton5(); } private Singleton5(){} public static Singleton5 getInstance(){ return SingletonHandler.INSTANCE; }
--读取实例的时候不会进行同步,没有性能缺陷,也不依赖JDK版本。
5.双重校验锁(推荐)
可能会有多个线程一起进入同步块外的if,如果在同步块内不进行二次检验的话就会生成多个实例了。
public class Singleton6 { private static Singleton6 instance; private Singleton6(){} public static Singleton6 getSingleton6(){ if(instance==null){ synchronized(Singleton6.class){ if(instance==null){ instance = new Singleton6(); } } } return instance; }
public class Singleton6 { private volatile static Singleton6 instance; private Singleton6(){} public static Singleton6 getSingleton6(){ if(instance==null){ synchronized(Singleton6.class){ if(instance==null){ instance = new Singleton6(); } } } return instance; }
--线程安全但效率低
6.枚举
public class Singleton7 { public enum EasySingleton{ INSTANCE; } }
--创建枚举默认就是线程安全,而且还能防止反序列化导致重新创建新的对象。可直接通过EasySingleton.INSTANCE来访问。
参考:bingogirl博文