登录
注册
写文章
发现
工具
java双重校验锁实现对象单例(线程安全)
_3t3lfz KEKfID
编辑文章
java双重校验锁实现对象单例(线程安全)
asfx站长
2020.12.21 22:21:59
阅读
775
双重校验锁实现对象单例(线程安全) ``` public class Singleton { private volatile static Singleton uniqueInstance; private Singleton() { } public static Singleton getUniqueInstance() { //先判断对象是否实例化过,没有实例化才能进入加锁代码 if (uniqueInstance == null) { //类对象加锁 synchronized (Singleton.class) { if (uniqueInstance == null){ uniqueInstance = new Singleton(); // 非原子操作 } } } return uniqueInstance; } } ``` 其中,uniqueInstance要用volatile关键字修饰。 因为 uniqueInstance = new Singleton();这段代码的执行过程是非原子性的,具体为以下三个步骤: 1.为uniqueInstance分配内存空间 2.初始化uniqueInstance 3.将uniqueInstance指向分配的内存地址 ##### volatile关键字可以禁止jvm的指令重排,保证在多线程环境下也能正常运行。 由于 JVM 具有指令重排的特性,执行顺序有可能变成 1->3->2。指令重排在单线程环境下不会出现问题,但是在多线程环境下会导致一个线程获得还没有初始化的实例。 例如,线程 a 执行了 1 和 3,此时 线程 b 调用 getUniqueInstance() 后发现 uniqueInstance 不为空,因此返回uniqueInstance,但此时 uniqueInstance 还未被初始化,所以就会导致空指针异常。
我的主页
退出