在一个公众号的大神文章中,看了一篇关于单例文章,特此记录一下。
一、双重校验单例模式
代码:
public class Singleton {
private Singleton() {} //私有构造函数
//关键:增加了一个 volatile 修饰符
private volatile static Singleton instance = null; //单例对象
//静态工厂方法
public static Singleton getInstance() {
if (instance == null) { //双重检测机制
synchronized (Singleton.class){ //同步锁
if (instance == null) { //双重检测机制
instance = new Singleton();
}
}
}
return instance;
}
}
说明:
正常建立对象,经过步骤:1、分配内存空间 2、初始化对象 3、设置对象指向刚分配的内存地址
如果没有使用 volatile 修饰符,因为JVM编译器的指令重排机制,有可能导致在 new singleton() 方法建立对象的时候,命令顺序改变,有可能A线程在建立对象的时候,执行了步骤1和步骤3,2还没有执行,此时线程B执行的话,对象为null,导致线程不安全。
volatile 修饰符就是为了保证指令按照正常的顺序执行,避免发生上面的情况。
PS:本文如果有错误,特请指出,便于修改学习!
二、静态内部类实现单例模式
代码:
public class Singleton {
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}