volatile作用,实现原理,运用场景:
①作用:volatile只能保证多线程三大特性中的可见性和有序性。
1)可见性:每个线程都有一个自己的本地内存,对于共享变量,线程每次读取和写入的都是共享变量在本地内存中的副本,然后在某个时间点将本地内存和主内存的值进行同步。而当修改volatile修饰的变量后,volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,会强制把对变量的修改同步到主内存。而其它线程在读取自己的本地内存中的值的时候,发现是volatile修饰的且已经被修改了,会把自己本地内存中的值置为无效,然后从主内存中读取。
2)有序性:在执行程序时,为了提高性能,处理器和编译器常常会对指令进行重排序,这种重排序一般只能保证单线程下执行结果不被改变。当被volatile修饰的变量后,将会禁止重排序。
②实现原理:
1)代码层面实现:通过内存屏障来实现的。
所谓的内存屏障,是在某些指令中插入屏障指令。虛拟机读取到这些屏障指令时主动将本地内存的变量值刷新到内存,或直接从主内存中读取变量的值。通过屏障指令会禁止屏障前的操作命令和屏障后的命令进行重排序
2)系统层面实现:在多处理器下,保证各个处理器的缓存是一致的,每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置成无效状态。
③使用场景:
1:多线程间状态标识
2:单例模式中双重检查锁的写法
3:定期观察成员变量状态的方法
附:
当且仅当满足以下所有条件时,才应该使用volatile变量:
•对变量的写入操作不依赖变量的当前值,或者能确保只有单个线程更新变量的值
•该变量不会与其他状态变量一起纳入不变性条件中
•在访问变量时不需要加锁