博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AtomicLong.lazySet是如何工作的?
阅读量:6307 次
发布时间:2019-06-22

本文共 973 字,大约阅读时间需要 3 分钟。

  译者:孙文强

说:

为一个AtomicLong对象设置一个值,jvm会确保其他线程读取到最新值,原子类和voliatile变量也是一样的,这是由依赖于硬件的系统指令(如x86的xchg)实现的。lazySet却是无法保证这一点的方法,所以其他线程在之后的一小段时间里还是可以读到旧的值。

这有什么好处呢?

性能:在多核处理器下,内存以及cpu缓存的读和写常常是顺序执行的,所以在多个cpu缓存之间同步一个内存值的代价是很昂贵的。

如何实现呢?

大多数的原子类,比如AtomicLong本质上都是一个Unsafe和一个volatile Long变量的包装类。值得注意的是AtomicLong.lazySet方法实际是调用了本地方法Unsafe.putOrderedLong,本地方法Unsafe.putOrderedLong的实现可以参考。从Unsafe的代码中可以发现Unsafe_setOrderedLong是一个本地方法(c++实现),它仅调用了SET_FIELD_VOLATILE,这很是奇怪,我们期望共享的Unsafe_setLongVolatile拥有不同的语义。PS:在非增强版本中,setOrdered仅仅是调用了setVolatile方法,很是让人失望。深入查看你会发现其实他们是相同的,SET_FIELD_VOLATILE是一个OrderAccess:release_store_fence的包装。可以在Linux x86的代码中找到此方法的实现,在64bit x86系统中采用xchgq来代码,64位版本指令的问题我上面有提到过。

ps:从理论上讲lazySet能比一个标准的volatile变量的写性能更好。但是我在openJdk里没有找到相关代码。

说:

sun.misc.unsafe很多方法被jvm增强了,JIT(just in time运行时编译执行的技术)直接解释而忽略原始的实现。可以在这里找到这个例子:列表中的native方法仅仅是非JIT环境下的一个备份的内部方法。例如,如果它没有被调用(我也不知道是什么原因),因此这些方法缺乏一些必要的优化。从的幻灯片11-12可以看到AtomicLong.lazySet(…)在x86系统上会被编译成“mov”指令。这里是里关于如何获得JIT装配的一个描述。

文章转自 

转载地址:http://svsxa.baihongyu.com/

你可能感兴趣的文章
mybatis(5) -自定义sql拦截统计执行耗时
查看>>
U盘中了蠕虫病毒后清除蠕虫并恢复文件的方法
查看>>
Linux 文件的权限设置
查看>>
04、navicat无法连接阿里云mysql
查看>>
查看JVM使用的什么垃圾收集器
查看>>
讲述下 :LVM逻辑卷管理遇到的问题
查看>>
jquery实用博客
查看>>
ORACLE日期时间函数大全(一)
查看>>
wpf通用窗体模板
查看>>
快速切换到主线程更新UI的几种方法
查看>>
jsp页面
查看>>
JS中ajax请求提交form表单
查看>>
list集合常用方法
查看>>
shell中的数组
查看>>
linux的usr目录的全称是什么?
查看>>
Java 8 新特性
查看>>
Kibana功能一览
查看>>
微信小程序开发系列六:微信框架API的调用
查看>>
jmeter压测和redis压测
查看>>
合并单元格后如何按序列排号?
查看>>