volatile:
相当于轻量级的synchronized,只能用来修饰变量,线程安全的三个特性通过volatile能实现其中的两个
原子性:
在之前的文章有说到,通过Atomic相关类、synchronized、lock都能够实现原子性,也就是共享变量的访问互斥。但是volatile无法保证
可见性:
导致共享变量在线程间不可见的原因:
1、线程交叉执行 2、重排序结合线程交叉执行 3、共享变量的值没有在工作内存和主存之间及时更新如何实现可见性:
1、通过加入内存屏障来实现
2、对volatile变量进行读写操作,都会通过store、load来强制从主存中读取最新的值,或将数据强制刷新到主存中。
有序性:
只要满足happens-before原则,就能保证先天的有序性,否则就可能发生指令重排序
synchronized和volatile实现有序性的区别:
1、volatile:关键字会禁止指令重排
2、synchronized:保证同一时刻只允许一条线程操作。
使用场景:
1、不适合计数场景,因此无法保证原子性
2、适合作为状态标示量,多线程下作为flag
3、doubleCheck
单例doubleCheck实现:
public class SingletonExample { // 私有构造函数 private SingletonExample() { } //分配内存一共有三步 // 1、memory = allocate() 分配对象的内存空间 // 2、ctorInstance() 初始化对象 // 3、instance = memory 设置instance指向刚分配的内存 // 单例对象 volatile + 双重检测机制 -> 禁止指令重排 private volatile static SingletonExample instance = null; // 静态的工厂方法 public static SingletonExample getInstance() { if (instance == null) { // 双重检测机制 synchronized (SingletonExample.class) { // 同步锁 if (instance == null) { instance = new SingletonExample(); } } } return instance; }}