单例模式经常会使用,但是在多线程环境下,不规范的单例写法还是会出现单例对象并非单例。这里分享两个常用的线程安全的单例模式,当然还有其他实现线程安全的单例。
1、双层检测
public class Instance implements Serializable {
/**
* @since JDK 1.7
*/
private static final long serialVersionUID = -4827759752671402638L;
private volatile static Instance instance = null;
private Instance(){}
//双层检测,在1.5以后Instance对象开始提供volatile关键字修饰变量来达到稳定效果
public static Instance getInstance(){
if(instance == null){
//注意是synchronized 字节码,不是synchronized 对象
synchronized(Instance.class){
if(instance == null){
instance = new Instance();
}
}
}
return instance;
}
@Override
public String toString() {
return "DCL检测";
}
/**
* 因实现Serializable接口。反序列化单例需要 ,在反序列化时会被调用,若不加此方法 则反序列化的类不是单例的
*/
private Object readResolve() throws ObjectStreamException {
return getInstance();
}
}
2、静态内部类
public class Instance2 implements Serializable {
/**
* @since JDK 1.7
*/
private static final long serialVersionUID = 6921443757360064842L;
private Instance2(){}
//静态内部类
private static class Instance2Holder{
private static Instance2 instance = new Instance2();
}
public static Instance2 getInstance(){
return Instance2Holder.instance;
}
@Override
public String toString() {
return "静态内部类";
}
/**
* 因实现Serializable接口。反序列化单例需要 ,在反序列化时会被调用,若不加此方法 则反序列化的类不是单例的
*/
private Object readResolve() throws ObjectStreamException {
return getInstance();
}
}
运行截图: