深入探讨java多线程中的volatile变量

深入探讨java多线程中的volatile变量

ID:30861830

大小:78.16 KB

页数:6页

时间:2019-01-04

深入探讨java多线程中的volatile变量_第1页
深入探讨java多线程中的volatile变量_第2页
深入探讨java多线程中的volatile变量_第3页
深入探讨java多线程中的volatile变量_第4页
深入探讨java多线程中的volatile变量_第5页
资源描述:

《深入探讨java多线程中的volatile变量》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库

1、深入探讨Java多线程中的volatile变量这篇文章主要为大家详细并深入的探讨Java多线程中的volatile变量,volatile用来确保将变量的更新操作通知到其他线程,保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新,感兴趣的小伙伴们可以参考一下volatile变量提供了线程的可见性,并不能保证线程安全性和原子性。什么是线程的可见性:锁提供了两种主要特性:互斥(mutualexclusion)和可见性(visibility)。互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数

2、据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,它必须确保释放锁之前对共亨数据做出的更改对于随后获得该锁的另一个线程是可见的-如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或不一致的值,这将引发许多严重问题。具体看volatile的语义:volatile相当于synchronized的弱实现,也就是说volatile实现了类似synchronized的语义,却又没有锁机制。它确保对volatile字段的更新以可预见的方式告知其他的线程。volatile包

3、含以下语义:(l)Java存储模型不会对valatile指令的操作进彳亍重排序:这个保证对volatile变量的操作时按照指令的出现顺序执行的。⑵volatile变量不会被缓存在寄存器中(只有拥有线程可见)或者其他对CPU不可见的地方,每次总是从主存中读取volatile变量的结果。也就是说对于volatile变量的修改,其它线程总是可见的,并且不是使用自己线程栈内部的变量。也就是在happens-before法则中,对一个valatile变量的写操作后,其后的任何读操作理解可见此写操作的结果。尽管volatile

4、变量的特性不错,但是volatile并不能保证线程安全的,也就是说volatile字段的操作不是原子性的,volatile变量只能保证可见性(一个线程修改后其它线程能够理解看到此变化后的结果),要想保证原子性,目前为止只能加锁!使用Volatile的原则:应用volatile变量的三个原则:(1)写入变量不依赖此变量的值,或者只有一个线程修改此变量(2)变量的状态不需要与其它变量共同参与不变约束(3)访问变量不需耍加锁实际上,这些条件表明,可以被写入volatile变量的这些有效值独立于任何程序的状态,包括变量的当

5、前状态。第一个条件的限制使volatile变量不能用作线程安全计数器。虽然增量操作(x++)看上去类似一个单独操作,实际上它是一个由读取-修改-写入操作序列组成的组合操作,必须以原子方式执行,而volatile不能提供必须的原子特性。实现正确的操作需要使x的值在操作期间保持不变,而volatile变量无法实现这点。(然而,如果将值调整为只从单个线程写入,那么可以忽略第一个条件。)大多数编程情形都会与这三个条件的其中之一冲突,使得volatile变量不能像synchronized那样普遍适用于实现线程安全。清单1显示

6、了一个非线程安全的数值范围类。它包含了一个不变式-下界总是小于或等于上界。正确使用volatile:模式#1:状态标志也许实现volatile变量的规范使用仅仅是使用一个布尔状态标志,用于指示发生了一个重要的一次性事件,例如完成初始化或请求停机。很多应用程序包含了一种控制结构,形式为“在还没有准备好停止程序时再执行一些工作“,如清单2所示:清单2.将volatile变量作为状态标志使用volatilebooleanshutdownRequested;…publicvoidshutdownf){shutdownReq

7、uested=true;}publicvoiddoWork(){while(IshutdownRequested){//dostuff}}很可能会从循环外部调用shutdown()方法-即在另一个线程中-因此,需要执行某种同步来确保正确实现shutdownRequested变量的可见性。(可能会从JMX侦听程序、GUI事件线程中的操作侦听程序、通过RMI、通过一个Web服务等调用)。然而,使用synchronized块编写循环要比使用清单2所示的volatile状态标志编写麻烦很多。由于volatile简化了编码,

8、并且状态标志并不依赖于程序内任何其他状态,因此此处非常适合使用volatile.这种类型的状态标记的一个公共特性是:通常只有一种状态转换;shutdownRequested标志从false转换为true,然后程序停止。这种模式可以扩展到来回转换的状态标志,但是只有在转换周期不被察觉的情况下才能扩展(从false到true,再转换到false)0此外,还需要某

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

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

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