理解AtomicXXX.lazySet方法
来源:互联网 发布:hough算法检测直线 编辑:程序博客网 时间:2024/06/07 16:21
http://blog.csdn.net/ITer_ZC/article/details/40744485
看过Java.util.concurrent.atomic包里面各个AtomicXXX类实现的同学应该见过lazySet方法,比如AtomicBoolean类的lazySet方法
它的底层实现调用了Unsafe的putOrderedInt方法,来看看putOrderedXXX方法的JavaDoc
它的意思是putOrderedXXX方法是putXXXVolatile方法的延迟实现,不保证值的改变被其他线程立即看到
理解volatile底层实现的同学知道,volatile的实现最终是加了内存屏障,
1. 保证写volatile变量会强制把CPU写缓存区的数据刷新到内存
2. 读volatile变量时,使缓存失效,强制从内存中读取最新的值
3. 由于内存屏障的存在,volatile变量还能阻止重排序
所以volatile变量的修改可以立刻让所有的线程可见,保证了可见性。而不加volatile变量的字段,JMM不保证普通变量的修改立刻被所有的线程可见。所以lazySet说白了就是以普通变量的方式来写变量。
那么为什么需要lazySet方法呢?其实它是一种低级别的优化手段,对上层调用者来说,其实很少用到。下面说说用lazySet的一个场景。
在这篇 聊聊高并发(十六)实现一个简单的可重入锁 中我们实现了一个可重入锁,里面共享变量用了volatile变量,来保证对共享变量的修改对其他线程可见。
但是事实上,这里完全可以不用volatile变量来修饰这些共享状态,
1. 因为访问共享状态之前先要获得锁, Lock.lock()方法能够获得锁,而获得锁的操作和volatile变量的读操作一样,会强制使CPU缓存失效,强制从内存读取变量。
2. Lock.unlock()方法释放锁时,和写volatile变量一样,会强制刷新CPU写缓冲区,把缓存数据写到主内存
底层也是通过加内存屏障实现的。
而lazySet()的用法和上面的优化是一个道理,就是在不需要让共享变量的修改立刻让其他线程可见的时候,以设置普通变量的方式来修改共享状态,可以减少不必要的内存屏障,从而提高程序执行的效率。
下面的例子来自StackOverflow上的一个提问,说的也是类似的意思,就是优化不必要的volatile操作。被墙的同学看不到,可以看截图。
- 理解AtomicXXX.lazySet方法
- 聊聊高并发(十八)理解AtomicXXX.lazySet方法
- J.U.C原子工具类AtomicXXX中,set和lazySet的区别
- 不要使用equals方法对AtomicXXX进行是否相等的判断
- 不要使用equals方法对AtomicXXX进行是否相等的判断
- AtomicLong.lazySet是如何工作的?
- 从AtomicXXX稍微说一下Unsafe
- SuspendLayout()方法的理解
- Render()方法理解
- servicerepaints方法理解
- 理解指针的方法
- 虚方法 形象理解
- 理解main方法
- onMeasure方法理解
- $.proxy方法的理解
- 扩展方法的理解
- 理解Collections.sortL() 方法
- ROW_NUMBER()方法理解
- 文章标题
- cocos2dx-lua检测触摸点是否在三角形内
- 编写shell脚本对mysql数据库进行定时备份
- 关于LeetCode中Symmetric Tree一题的理解
- Java Web提交参数到Spark集群执行任务
- 理解AtomicXXX.lazySet方法
- C#控制台基础 全角与半角如何切换 全角半角输出的区别
- 二叉树中和为某一值的路径
- JS XLS/X的使用心得
- CSU 1804 有向无环图【湖南省第十二届大学生计算机程序设计竞赛 B题 DAG】
- POJ3463 求次短路径条数
- hibernate 逆向工程对数据库进行CRUD操作
- MySQL特殊需求总结及其实现方法
- hdu2553