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博文