![image](http://ws2.sinaimg.cn/large/e0e01e43ly1g186ftl4a0j21g80yt4qt.jpg)
volatile简介
volatile
被称为轻量级的synchronized,运行时开销比synchronized
更小,在多线程并发编程中发挥着同步共享变量、禁止处理器重排序的重要作用。建议在学习volatie
之前,先看一下Java内存模型《什么是Java内存模型?》,因为volatile
和Java内存模型有着莫大的关系。
Java内存模型
在学习volatie
之前,需要补充下Java内存模型的相关(JMM)知识,我们知道Java线程的所有操作都是在工作区进行的,那么工作区和主存之间的变量是怎么进行交互的呢,可以用下面的图来表示。
Java通过几种原子操作完成工作区内存和主存的交互
- lock:作用于主存,把变量标识为线程独占状态。
- unlock:作用于主存,解除变量的独占状态。
- read:作用于主存,把一个变量的值通过主存传输到线程的工作区内存。
- load:作用于工作区内存,把
read
操作传过来的变量值储存到工作区内存的变量副本中。 - use:作用于工作内存,把工作区内存的变量副本传给执行引擎。
- assign:作用于工作区内存,把从执行引擎传过来的值赋值给工作区内存的变量副本。
- store:作用于工作区内存,把工作区内存的变量副本传给主存。
- write:作用于主存,把
store
操作传过来的值赋值给主存变量。
这8
个操作每个操作都是原子性的,但是几个操作连着一起就不是原子性了!
volatile原理
上面介绍了Java模型的8
个操作,那么这8
个操作和volatile
又有着什么关系呢。
volatile的可见性
什么是可见性,用一个例子来解释,先看一段代码,加入线程1
先执行,线程2
再执行
//线程1
boolean stop = false;
while (!stop) {
do();
}
//线程2
stop = true;
线程1
执行后会进入到一个死循环中,当线程2
执行后,线程1
的死循环就一定会马上结束吗?答案是不一定,因为线程2
执行完stop = true
后,并不会马上将变量stop
的值true
写回主存中,也就是上图中的assign
执行完成之后,store
和write
并不