介绍:
保证被volatile修饰的共享变量对所有线程总是可⻅的,也就是当⼀个线程修改了⼀个被volatile修饰共享变量的值,新值总是可以被其他线程⽴即得知。
示例:
如果线程
2
改变了stop的值,线程
1
⼀定会停⽌吗?不⼀定。当线程
2
更改了stop变量的值之后,但是还没来得及写⼊主存当中,线程2
转去做其他事情了,那么线程
1
由于不知道线程
2
对stop变量的更改,因此还会⼀直循环下去。
//线程1
boolean stop = false;
while(!stop){
doSomething();
}
//线程2
stop = true;
禁⽌指令重排序优化
int a = 0;
bool flag = false;
public void write(){
a = 2; //1
flag = true; //2
}
public void multiply(){
if(flag){ //3
int ret = a * a; //4
}
}
write⽅法⾥的
1
和
2
做了重排序,线程
1
先对flag赋值为true,随后执⾏到线程
2
,ret直接计算出结果,再到线程1
,这时候a才赋值为
2
,很明显迟了⼀步。但是⽤volatile修饰之后就变得不⼀样了:
- 使⽤volatile关键字会强制将修改的值⽴即写⼊主存;
- 使⽤volatile关键字的话,当线程2进⾏修改时,会导致线程1的⼯作内存中缓存变量stop的缓存⾏⽆效(反映到硬件层的话,就是CPU的L1或者L2缓存中对应的缓存⾏⽆效);
-
由于线程1的⼯作内存中缓存变量stop的缓存⾏⽆效,所以线程1再次读取变量stop的值时会去主存读取。
而inc++;
其实是两个步骤,先加加,然后再赋值。不是原⼦性操作,所以volatile不能保证线程安全
![](https://img-blog.csdnimg.cn/0cb6997c47ee4c44b8f7e39e81f558be.jpeg)