找了很多资料,包括《Java并发编程实战》,综合一下各家的说法就是:
volatile让变量每次在使用的时候,都从主存中取。而不是从各个线程的“工作内存”。
volatile具有synchronized关键字的“可见性”,但是没有synchronized关键字的“并发正确性”,也就是说不保证线程执行的有序性。
也就是说,volatile变量对于每次使用,线程都能得到当前volatile变量的最新值。但是volatile变量并不保证并发的正确性。
看下面的例子:
假如count变量是volatile的。线程1,线程2 在进行read,load 操作中,发现主内存中count的值都是5,那么都会加载这个最新的值在线程1堆count进行修改之后,会write到主内存中,主内存中的count变量就会变为6,线程2由于已经进行read,load操作,在进行运算之后,也会更新主内存count的变量值为6,导致两个线程及时用volatile关键字修改之后,还是会存在并发的情况。
--------------------------------------
综合了查找到的资料,上面的解释,还算理解的过去。但是《java并发编程实战》上的例子,就不是很明白了。
看下面
----------------------------------------------------------------
java并发编程实战上说,如果变量不是volatile的,那么在被其他线程修改之后,之前的线程是不会感知到的。但是下面的代码,asleep被修改了之后,其他四个线程却都停止了输出。不明白是怎么回事。
----------------------------
那么,我们这里说线程要先拷贝变量到自己的工作内存,然后再使用。在这里,什么是线程的工作内存呢?
看看JLS(java语言规范)对线程工作内存的描述,线程的working memory只是cpu的寄存器和高速缓存的抽象描述。