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 可以用原子方式更新的 ...
随机推荐
- window配置右键菜单
window配置右键菜单 cmd -> regeidt :打开注册表 文件右键 依次点开HKEY_CLASSES_ROOT ---> * ---> shell. 右键shell,新建 ...
- python魔法方法-属性转换和类的表示
类型转换魔法 类型转换魔法其实就是实现了str.int等工厂函数的结果,通常这些函数还有类型转换的功能,下面是一些相关的魔法方法: __int__(self) 转换成整型,对应int函数. __lon ...
- NOIP 2006 作业调度方案
[问题描述] 我们现在要利用m台机器加工n个工件,每个工件都有m道工序,每道工序都在不同的指定的机器上完成.每个工件的每道工序都有指定的加工时间. 每个工件的每个工序称为一个操作,我们用记号j-k表示 ...
- vs2010中关于HTML控件与服务器控件分别和js函数混合使用的问题
此文档解决以下问题: 1.在.cs文件中如何访问html控件? 在html控件中添加属性runat="server"即可 2.在html控件中,如何调用js函数? 在html控件中 ...
- Android HttpURLConnection.connect找不到源 HttpURLConnection连接失败 HttpURLConnection.connect IO异常 解决办法
Android HttpURLConnection.connect找不到源 HttpURLConnection连接失败 HttpURLConnection.connect IO异常 解决办法 以下代 ...
- JDBC(5)—DatabaseMetaData
1.简介: 使用元数据已实现通用的查询方法.元数据介绍:使用jdbc获得连接之后,得到一个Connection对象,可以通过这个对象获得DataBaseMetaData对象,该对象可以获得有关数据库管 ...
- [Java web]Spring+Struts2+Hibernate整合过程(2)
摘要 上篇文章介绍了一种整合方式,不妨就叫做有hibernate配置文件的方式,这里介绍一种不用hibernate.cfg.xml的一种配置方式,为了方便,就仍在上篇的demo中,继续修改了. 步骤 ...
- copy unicode HTML to clipboard
How to copy unicode HTML code to the clipboard in html format, so it can be pasted into Writer, Word ...
- arcgis pro行列转换
行转列 列转行
- ConcurrentLinkedQueue代码解析
原因:学习ConcurrentLinkedQueue是看到akka框架的默认邮箱是使用ConcurrentLinkedQueue实现的. 1. ConcurrentLinkedQueue在java.u ...