1、volatitle是java的一种轻量级的并发机制
2、被volatitle修饰的关键字也存在并发问题
3、一般的变量在使用时需要把变量从主内存控件加载到工作内存空间(可以映射为堆内存和栈内存模型),工作内存空间是线程私有,然后使用外之后才能更新到主内存,这期间的操作不是原子操作,所以在高并发下,存在存储不一致问题。
4、volatitle关键字修饰的变量能够保证每次在工作空间使用内存时从主内存刷新变量的值,改变之后跟新到主内存,但是在使用的时候并不能保证是原子操作,在更新内存的之前,可能其他线程已经改变了变量 的值了,所以还是存在并发问题。只是比普通的变量“更可靠”罢了。
5、所以volatitle关键字只能保证可见性。我们仍然需要加synchronize或者concurrent包里面的类来保证原子性。
在不符合下面两条规则的场景中,仍需要枷锁:
1、运算结果并不依赖变量当前的值,或者保证只有单一线程修改变量的值
2、变量不需要与其他状态变量共同参与不变约束。
比如下列场景就是好volatitle关键字:
volatitle boolean isRun;
public void changeState() {
isRun = fasle;
}
public void run() {
while(isRun ) ....
}
当changeState方法执行的时候,其他线程的run方法立即停止执行。
使用volatitle的第二个语义是禁止指令重排(指令重排:多条指令交给cpu执行的时候,可以进行优化,不按顺序交给多条电路执行),指令重排会造成同一段代码多次执行的顺序不一定相等。
- 原子性、可见性、有序性
有序性:在线程内部观察都是有序的,在一个线程观察另一个线程都是无序的。前半句是指线程串行语义,后半句是指指重排现象和工作内存与主内存同步现象。