众所周知,在java中单例模式实现有7种,分别如下:
public class Singleton{
private static Singleton instance;
private Singleton(){};
public static Singleton getInstance(){
if(instance == null ){
instance = new Singleton();
}
return instance;
}
}
这种模式采用懒加载lazy loading但是在多线程下不安全
public class Singleton{
private static Singleton instance;
private Singleton(){};
public static synchronized Singleton getInstance(){
if(instance == null ){
instance = new Singleton();
}
return instance;
}
}
懒加载,线程安全,但效率极其低下,同步锁锁的是对象,每次取对象都加锁,因此效率低下
public class Singleton{
private static Singleton instance= new Singleton();
private Singleton(){};
public static Singleton getInstance(){
return instance;
}
}
这种方式基于classloader机制避免了多线程同步问题,不过instance在类装载时就实例化,没有达到懒加载效果
public class Singleton{
private static Singleton instance = null;
static{
instance= new Singleton();
}
private Singleton(){};
public static Singleton getInstance(){
return instance;
}
}
等同于第三种
public class Singleton{
private Singleton(){};
public static synchronized Singleton getInstance(){
return SingletonInnerClass.instance;
}
private static class SingletonInnerClass(){
private static Singleton instance = new Singleton();
}
}
利用classloader机制保证初始化实例时只有一个实例,与第三种第四种差别是达到了懒加载效果(第三种第四种方法只要singleton类被装载了那么instance就会被实例化,而这种方式SingletonInnerClass类没有被主动使用,只有被显示调用getInstance时才会显示装载SingletonInnerClass类,从而实现懒加载)在实例化instance很消耗资源,想让他延迟加载,另外不希望在singleton类加载时就实例化,这种方式就显得很合理 。推荐使用
public class Singleton{
private static Singleton instance;
private Singleton(){};
public static synchronized Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
不管性能如何优越,使用了synchronized修饰符,就会对性能多少造成影响
public enum SIngleton{
INSTANCE;
public void whateverMethod(){}
}
这种方式是Effective Java提倡方式,不仅能避免多线程同步问题,还能防止反序列化重新创建新的对象,但因为可读性原因不推荐
由此七方法也介绍完毕,但也有几个问题需要反思
public class Singleton3{
private static boolean initialized = false;
private Singleton3(){
synchronized(Singleton3.class){
if(initialized == false){
initialized = !initialized ;
}else{
throw new RuntimeException("单例已破坏");
}
}
}
static class SingletonHolder{
private static final Singleton3 instance = new Singleton3();
}
public static Singleton3 getInstance(){
return SingletonHolder.instance;
}
}
这就保证了反射无法破坏其单例
public class Singleton4 implements Serializable{
private static boolean initialized = false;
private Singleton4(){
synchronized(Singleton4.class){
if(initialized == false){
initialized = !initialized ;
}else{
throw new RuntimeException("单例已破坏");
}
}
}
static class SingletonHolder{
private static final Singleton4 instance = new Singleton4();
}
public static Singleton4 getInstance(){
return SingletonHolder.instance;
}
private Object readResolve(){
return getInstance();
}
}