AtomicLong.lazySet 是如何工作的?
原文:http://www.quora.com/Java-programming-language/How-does-AtomicLong-lazySet-work
Jackson Davis说:为一个 AtomicLong 对象设置一个值,JVM 会确保其他线程读取到最新值,原子类和 voliatile 变量也是一样的,这是由依赖于硬件的系统指令(如 x86 的 xchg )实现的。lazySet 却是无法保证这一点的方法,所以其他线程在之后的一小段时间里还是可以读到旧的值。
这有什么好处呢?
性能:在多核处理器下,内存以及 CPU 缓存的读和写常常是顺序执行的,所以在多个 CPU 缓存之间同步一个内存值的代价是很昂贵的。
如何实现呢?
大多数的原子类,比如 AtomicLong 本质上都是一个 Unsafe 和一个 volatile Long 变量的包装类。值得注意的是 AtomicLong.lazySet 方法实际是调用了本地方法 Unsafe.putOrderedLong,本地方法 Unsafe.putOrderedLong 的实现可以参考 http://hg.openjdk.java.net/jdk7/…。
public final void lazySet(int newValue) { unsafe.putOrderedInt(this, valueOffset, newValue);}
从 Unsafe 的代码中可以发现 Unsafe_setOrderedLong 是一个本地方法(c++ 实现),它仅调用了 SET_FIELD_VOLATILE,这很是奇怪,我们期望共享的 Unsafe_setLongVolatile 拥有不同的语义。
PS:在非增强版本中,setOrdered 仅仅是调用了 setVolatile 方法,很是让人失望。深入查看你会发现其实它们是相同的,SET_FIELD_VOLATILE 是一个 OrderAccess:release_store_fence 的包装。可以在 Linux x86的代码 http://hg.openjdk.java.net/jdk7/… 中找到此方法的实现,在 64bit x86 系统中采用 xchgq 来代码,64位版本指令的问题我上面有提到过。
ps:从理论上讲 lazySet 能比一个标准的 volatile 变量的写性能更好。但是我在 openJdk 里没有找到相关代码。
Felix Sulima说:
sun.misc.unsafe 很多方法被 JVM 增强了,JIT(just in time 运行时编译执行的技术)直接解释而忽略原始的实现。可以在这里找到这个例子:src/share/vm/classfile/vmSymbols.hpp@3facbb14e873列表中的 native 方法仅仅是非 JIT 环境下的一个备份的内部方法。例如,如果它没有被调用(我也不知道是什么原因),因此这些方法缺乏一些必要的优化。从 Talk from JAX London 的幻灯片 11-12 可以看到 AtomicLong.lazySet(…) 在 x86 系统上会被编译成 "mov" 指令。这里是 Google Group 里关于如何获得 JIT 装配的一个描述。
看的一脸懵逼。
AtomicLong.lazySet 是如何工作的?的更多相关文章
- JDK中的Atomic包中的类及使用
引言 Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下,无锁的进行原子操作.原子变量的底层使用了处理器提供的原子指令,但是不同的CPU ...
- JAVA多线程提高五:原子性操作类的应用
当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i=1,A线程更新i+1,B线程也更新i+1,经过两个线程操作之后可能i不等于3,而是等于2.因为A和B线程在更新变量i ...
- Java中的原子操作类
转载: <ava并发编程的艺术>第7章 当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i=1,A线程更新i+1,B线程也更新i+1,经过两个线程操作之后可 ...
- JAVA多线程学习九-原子性操作类的应用
当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i=1,A线程更新i+1,B线程也更新i+1,经过两个线程操作之后可能i不等于3,而是等于2.因为A和B线程在更新变量i ...
- 二、多线程之Atomic包
一.简介 1.原子操作 我们在使用变量的时候,经常会出现资源竞争的情况,为了保证变量安全,我们就会对对应的方法添加"synchronized"同步锁来达到目的,以保证线程安全. 而 ...
- 详解volatile关键字和原子引用
本篇看一下Volatile关键字和原子引用. 上图就是JUC包结构,总共分成三块 (1)java.util.concurrent:并发包基础类,包括阻塞队列,线程池相关类,线程安全Map等. (2)j ...
- 从零开始实现lmax-Disruptor队列(一)RingBuffer与单生产者、单消费者工作原理解析
1.lmax-Disruptor队列介绍 disruptor是英国著名的金融交易所lmax旗下技术团队开发的一款java实现的高性能内存队列框架 其发明disruptor的主要目的是为了改进传统的内存 ...
- Java多线程系列--“JUC原子类”02之 AtomicLong原子类
概要 AtomicInteger, AtomicLong和AtomicBoolean这3个基本类型的原子类的原理和用法相似.本章以AtomicLong对基本类型的原子类进行介绍.内容包括:Atomic ...
- 多线程爬坑之路-J.U.C.atomic包下的AtomicInteger,AtomicLong等类的源码解析
Atomic原子类:为基本类型的封装类Boolean,Integer,Long,对象引用等提供原子操作. 一.Atomic包下的所有类如下表: 类摘要 AtomicBoolean 可以用原子方式更新的 ...
随机推荐
- Jmeter脚本录制方法(二)手工编写脚本(jmeter与fiddler结合使用)
jmeter脚本录制方法可以分三种,前几天写的一篇文章中,已介绍了前两种,今天来说下第三种,手工编写脚本,建议使用这一种方法,虽然写的过程有点繁琐,但调试脚本比前两者方式都要便捷. 首先来看下三种方式 ...
- css 背景透明色, 文字不透明。
[原]CSS实现背景透明,文字不透明,兼容所有浏览器 background-color: rgba(0,0,0,0.5); filter:Alpha(opacity=50);
- 洛谷.1501.[国家集训队]Tree II(LCT)
题目链接 日常zz被define里没取模坑 //标记下放同线段树 注意51061^2 > 2147483647,要开unsigned int //*sz[]别忘了.. #include < ...
- Python3练习题系列(09)——物以类聚,人以群分
目标: 用类管理同类事物 解析: 用到“class”的编程语言被称作“Object Oriented Programming(面向对象编程)”语言.首先你需要做出“东西”来,然后你“告诉”这些东西去完 ...
- jsp导出简单的excel
在jsp中加入以下代码即可 <% String fileName = "导出excel.xls"; fileName = new String(fileName.getByt ...
- IAAS、SAAS 和 PAAS 的区别、理解
通俗的讲: 如果你是一个网站站长,想要建立一个网站.不采用云服务,你所需要的投入大概是:买服务器,安装服务器软件,编写网站程序.现在你追随潮流,采用流行的云计算,如果你采用IaaS服务,那么意味着你就 ...
- 【转】Intellij IDEA调试功能
http://www.cnblogs.com/winner-0715/p/5422952.html 先编译好要调试的程序.1.设置断点
- iOS 跳转到系统指定设置界面
在需要调转的按钮动作中添加如下的代码,就会跳转到设置中自己的app的设置界面,这里会有通知和位置权限的设置 NSURL * url = [NSURLURLWithString:UIApplicatio ...
- apache 通过ajp访问tomcat多个站点
copy mod_jk.so to modules下 httpd的配置项中添加如下内容 LoadModule proxy_module modules/mod_proxy.so LoadModule ...
- 微信小程序wxss的background本地图片问题
在web 或者webapp开发中我们习惯了直接饮用本地图片做背景,例如 .aaa { background: url('img/1.png'); } 但是这种引用方式在微信小程序中是无法使用的,控制台 ...