Java中双检锁里volatile的作用
程序员文章站
2022-07-14 09:09:57
...
懒汉式
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static 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;
}
}
双检锁(线程安全)
public class Singleton {
private volatile static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if (instance == null){ // 第一次检查
synchronized (Singleton.class){
if (instance == null) // 第二次检查
instance = new Singleton();
}
}
return instance;
}
}
Java中双检锁里volatile的作用
双检锁中在第二次检查后创建对象的代码instance = new Singleton();
可以分解为如下的3行伪代码
memory = allocate(); // 1.分配对象的内存空间
ctorInstance(memory); // 2.初始化对象
instance = memory; // 3.设置instance指向刚分配的内存地址
上面3行伪代码中的2和3之间,可能会被重排序。2和3之间重排序之后的执行时序如下:
memory = allocate(); // 1.分配对象的内存空间
instance = memory; // 3.设置instance指向刚分配的内存空间
ctorInstance(memory); // 2.初始化对象
这样在多线程下可能会发生问题,即当线程A执行完里面的1、3过程时,线程B在判断出instance不为空就会直接访问instance引用的对象。此时,线程B将会访问一个还未初始化的对象。
当声明对象的引用为volatile后,3行伪代码中的2和3之间的重排序,在多线程环境下将会被禁止,保证了线程安全的延迟初始化。
推荐阅读
-
深入解析Java中volatile关键字的作用
-
java中双检锁为什么要加上volatile关键字!
-
Java单例模式的不同写法(懒汉式、饿汉式、双检锁、静态内部类、ThreadLocal、枚举)
-
Java单例模式中双检锁的线程安全问题
-
Java中双检锁里volatile的作用
-
Java中的volatile关键字详解及单例模式双检锁问题分析
-
java filter里
中的 作用 -
浅谈 Java 中的 volatile 作用(一):线程可见性
-
简单概括PHP的字符串中单引号与双引号的区别 java字符串中有双引号 字符串中有双引号 字符串里有双引
-
Java中关键字volatile 和 synchronized 的作用和区别