volatile关键字的语义分析
Volatile作用:让其他线程能够马上感知到某一线程多某个变量的修改
(1)保证可见性
对共享变量的修改,其他的线程马上能感知到
不能保证原子性 读、写、(i++)
(2)保证有序性
重排序(编译阶段、指令优化阶段)
输入程序的代码顺序并不是实际执行的顺序
重排序后对单线程没有影响,对多线程有影响
Volatile
Happens-before
volatile规则:
对于volatile修饰的变量:
(1)volatile之前的代码不能调整到他的后面
(2)volatile之后的代码不能调整到他的前面(as if seria)
(3)霸道(位置不变化)
Int i=0;
Int a=3;
Int b=5;
Volatile Int j=3;
Int i=0;
Int a=3;
Int b=5;
Int m=i+j;
I++;
J++;
(3)volatile的原理和实现机制(锁、轻量级)
Volatile的使用场景
(1)状态标志(开关模式)
public class ShutDowsnDemmo extends Thread{
private volatile boolean started=false;@Override
public void run() {
while(started){
dowork();
}
}
public void shutdown(){
started=false;
}
}
Spring中的应用,用于通知其他线程已经存在的beanDefinitionName
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
......
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
(2)双重检查锁定(double-checked-locking)
DCL
public class Singleton {
private volatile static Singleton instance;
public static Singleton getInstance(){
if(instance==null){
synchronized (Singleton.class){
instance=new Singleton();
}
}
return instance;
}
}
volatile与synchronized的区别
(1)使用上的区别
Volatile只能修饰变量,synchronized只能修饰方法和语句块
(2)对原子性的保证
synchronized可以保证原子性,Volatile不能保证原子性
(3)对可见性的保证
都可以保证可见性,但实现原理不同
Volatile对变量加了lock,synchronized使用monitorEnter和monitorexit monitor JVM
(4)对有序性的保证
Volatile能保证有序,synchronized可以保证有序性,但是代价(重量级)并发退化到串行
(5)其他
synchronized引起阻塞
Volatile不会引起阻塞