您的位置:首页 > 其它

volatile关键字总结

2017-06-27 18:50 162 查看
Thinking in java中volatile关键字内容总结

第一部分 volatile保证可视性

原子性可以应用于处long和double之外的所有基本类型之上的“简单操作”,但是JVM可以将64位的读取和写入当作两个分离的32位操作来执行(字撕裂)。

当你定义long或double变量时,使用volatile,就会获得原子性

在多处理器系统上,相对于单处理器系统而言,可视性问题远比原子性问题多得多。一个任务做出的修改,即使在不中断的意义上讲是原子性的,对其他任务也可能是不可视的。

如,修改只是暂时性地存储在本地处理器的缓存中,因此不同的任务对应用的状态有不同的视图。

volatile关键字保证了应用中的可视性。如果你将一个域声明为volatile的,那么只要对这个域产生了写操作,那么所有的读操作就都可以看到这个修改,即便使用了本地缓存,情况也是如此,volatile域会直接写到主存中。

非volatile域上的原子操作不必刷新到主存中去,因此其他读取该域的任务可能看不到这个新值。

如果多个任务同时访问某个域,那么这个域就应该是volatile的,否则,这个域就应该只能经由同步来访问。同步机制也会导致在主存中刷新,因此如果一个域有synchronized方法或语句块来防护,不必使用volatile。

第二部分:volatile和synchronized的区别

不同

在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,

因此volatile变量是一种比sychronized关键字更轻量级的同步机制。

相同都是

保证了写入和读取都直接操作内存,不会进行内存的重排序或CPU cache等操作,保证可视性

使用volatile而不是synchronized的唯一安全的情况是类中只有一个可变的域

第三部分:volatile不能解决“原子性操作但是仍需要同步控制”的问题

“原子操作不需要进行同步控制”是不正确的。

尽管某个操作是原子性操作,但是仍有可能在其处于不稳定的中间状态时被读取。

在没有同步的情况下对共享可变值进行了访问,即使共享可变值设置为volatile,解决了多任务的可视性问题

但仍有可能在其处于不稳定的中间状态时被读取。

解决方案是添加同步控制
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: