Java中volatile的作用以及用法
2013-02-28 10:27
483 查看
找了很多资料,包括《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的寄存器和高速缓存的抽象描述。
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被修改了之后,其他四个线程却都停止了输出。不明白是怎么回事。
package comz; /** * 这段代码虽然没有volatile,但是另外的线程设置为true的时候,其他的四个线程依然停止了运行。 与书上不一致。为啥? * 书上说,如果不是volatile的,则另外的线程更新这个值的时候,其他的线程是不会感知到的。所以其他线程就不会停止执行。 * @author naughty * */ class T { public static boolean asleep = false; public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 4; i++) { new Thread(new Runnable() { @Override public void run() { judge(); } }).start(); } Thread.sleep(3000); new Thread(new Runnable() { public void run() { asleep = true; System.out.println("end"); } }).start(); } public static void judge() { while (!asleep) { try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } CMS(); } } public static void CMS() { System.out.println("@"); } }
----------------------------
那么,我们这里说线程要先拷贝变量到自己的工作内存,然后再使用。在这里,什么是线程的工作内存呢?
看看JLS(java语言规范)对线程工作内存的描述,线程的working memory只是cpu的寄存器和高速缓存的抽象描述。
相关文章推荐
- Java中volatile的作用以及用法 GOOD
- Java中volatile的作用以及用法
- Java中volatile的作用以及用法
- Java中volatile的作用以及用法
- java volatile是什么关键子,以及在线程中的作用。
- java:什么是抽象类,以及抽象类的作用和用法(abstract)
- java 内部类用法以及其作用
- java import、package作用与用法以及与C include的区别
- Java中volatile的作用以及它和synchronized的比较
- Java中volatile和synchronized 作用以及区别
- java:什么是抽象类,以及抽象类的作用和用法(abstract)
- java中的try catch的Exception起到什么作用以及用法
- Java中volatile关键字的作用与用法详解
- java中 equals的用法(object 和 其他类),以及与 == 的比较
- java中equals用法以及==的用法(面试坑)
- java作用域public protected private,以及不写时的区别
- 转:java中的volatile的用法
- Android Application.java以及它的作用
- hive中order by,sort by, distribute by, cluster by作用以及用法
- 【JAVA多线程】volatile关键字在JAVA多线程编程中的作用