java并发编程(18):第五篇中volatile意外问题的正确分析解答(含代码)-编程开发技术

java并发编程(18):第五篇中volatile意外问题的正确分析解答(含代码)-编程开发技术

ID:30768913

大小:212.71 KB

页数:5页

时间:2019-01-03

java并发编程(18):第五篇中volatile意外问题的正确分析解答(含代码)-编程开发技术_第1页
java并发编程(18):第五篇中volatile意外问题的正确分析解答(含代码)-编程开发技术_第2页
java并发编程(18):第五篇中volatile意外问题的正确分析解答(含代码)-编程开发技术_第3页
java并发编程(18):第五篇中volatile意外问题的正确分析解答(含代码)-编程开发技术_第4页
java并发编程(18):第五篇中volatile意外问题的正确分析解答(含代码)-编程开发技术_第5页
资源描述:

《java并发编程(18):第五篇中volatile意外问题的正确分析解答(含代码)-编程开发技术》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库

1、Java并发编程(18):第五篇中volatile意外问题的正确分析解答(含代码)-编程开发技术Java并发编程(18):第五篇中volatile意外问题的正确分析解答(含代码)原文出处:兰亭风雨在《Java并发编程(5:volatile变量修饰符一意料之外的问题(含代码)》一文屮遗留了一个问题,就是volatile只修饰了missedlt变量,而没修饰value变量,但是在线程读取value的值的时候,也读到的是最新的数据。但是在网上杳了很多资料都无果,看來很多人对volatile的规则并不是太清晰,

2、或者说只停留在很表而的层次,一知半解。这两犬看《深入Java虚拟机JVM高级特性与最佳实践》第12章:Java内存模型与线程,并在网上查阅了Java内存模型相关资料,学到了不少东西,尤其在看这篇文章的volatile部分的讲解之后,算是确定了问题出现的原因。首先明确一点:假如有两个线程分别读写volatile变量时,线程A写入了某volatile变量,线程B在读取该volatile变量时,便能看到线程A对该volatile变量的写入操作,关键在这里,它不仅会看到对该volatile变量的写入操作,A线程

3、在写volatile变量之前所有可见的共享变量,在B线程读同一个volatile变量后,都将立即变得对B线程可见。回过头來看文章中出现的问题,由于程序中volatile变量missedlt的写入操作在value变量写入操作Z后,而月.根据volatile规则,又不能重排序,因此,在线程B读取由线程A改变后的missedlt之后,它之前的value变量在线程A的改变也对线程B变得可见了。我们颠倒一下value=50和missedlt二true这两行代码试下,即missedlt二true在前,value二5

4、0在后,这样便会得到我们想耍的结果:value值的改变不会被看到。这应该是JDK1.2之后对volatile规则做了一些修订的结果。修改后的代码如下:publicclassVolatileextendsObjectimplementsRunnable{//value变量没有被标记为volatileprivateintvalue;//missedlt变量被标记为volatileprivatevolatilebooleanmissedlt;//creationTime不需要声明为volatile,因为代码执

5、行屮它没冇发生变化privatelongcreationTime;publicVolatile(){value=10;missedlt=false;//获取当前吋间,亦即调用Volatile构造函数吋的吋间creationTime二System.currentTimeMi11is();publicvoidrun(){print(''enteringrun()z,);//循环检查value的值是否不同while(value<20){//如果missedlt的值被修改为true,则通过break退出循环if

6、(missedIt){//进入同步代码块前,将value的值赋给currValucintcurrValue=value;//在一个任意对象上执行同步语句,目的是为了让该线程在进入和离开同步代码块吋,//将该线程中的所冇变量的私冇拷贝与共享内存中的原始值进行比较,//从而发现没冇用volatile标记的变量所发生的变化Objectlock二newObject();synchronized(lock){//不做任何事}//离开同步代码块后,将此时value的值赋给valueAfterSyncintvalue

7、AfterSync二value;print(〃inrun()-secvalue二"+currValuc+〃,butrumorhasitthatitchanged!,z);print(z/inrun()-valueAfterSync二〃+valueAfterSync);break;}print(''leavingrun()z,);publicvoidworkMethod()throwsInterruptedException{print(z/enteringworkMethod()z/);print("i

8、nworkMethod()-Thread,sleep(2000);//仅在此改变value的值missedlt=true;abouttosleepfor2seconds");//value二50;print("inworkMethod()--justsetvalue=,z+value);print(“inworkMethod()-Thread,sleep(5000);abouttosleepfor5seconds〃);//仅在此改变miss

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。