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 可以用原子方式更新的 ...
随机推荐
- CF 1131 E. String Multiplication
E. String Multiplication 题意 分析: 从后往前考虑字符串变成什么样子. 设$S_i = p_1 \cdot p_2 \dots p_{i}$,最后一定是$S_{n - 1} ...
- 洛谷.2042.[NOI2005]维护数列(Splay)
题目链接 2017.12.24 第一次写: 时间: 2316ms (1268ms) 空间: 19.42MB (19.5MB)(O2) 注:洛谷测的时间浮动比较大 /* 插入一段数:将这些数先单独建一棵 ...
- Python3练习题系列(01)
2018-06-13 题目: 根据用户回答做出相应的判断,完成一个“回答-判断”的小游戏 Python3知识点: if, else, elif 实例代码: print("You enter ...
- rabbitmq使用方法(一)
Introduction RabbitMQ is a message broker. The principal idea is pretty simple: it accepts and forwa ...
- 前端性能优化 —— 减少HTTP请求
简要:对于影响页面呈选 的因素有3个地方:服务器连接数据库并计算返回数据 , http请求以及数据(文件)经过网络传输 , 文件在浏览器中计算渲染呈选: 其中大约80%的时间都耗在了http请求上,所 ...
- exce中42093和日期之间的关系
在EXECEL中数字0 代表日期 1900-1-0 ,即这个日期为起始日期,算是第0天数字1 代表日期 1900-1-1 ,即第一天数字2 代表日期 1900-1-2 ,即第二天......数字415 ...
- Standard Series Values in a Decade for Resistances and Capacitances E24 E48 E96
E3 50% tolerance (no longer used)E6 20% tolerance (now seldom used)E12 10% toleranceE24 ...
- 【BZOJ3036】绿豆蛙的归宿 概率DP
链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网 ...
- 慎用ArrayList的contains方法,使用HashSet的contains方法代替
在启动一个应用的时候,发现其中有一处数据加载要数分钟,刚开始以为是需要load的数据比较多的缘故,查了一下数据库有6条左右,但是单独写了一个数据读取的方法,将这6万多条全部读过来,却只需要不到10秒钟 ...
- linux tomcat 绑定域名
1.解析域名到对应的服务器ip 2.找到tomcat安装路径进入/conf 3.vi server.xml 4.修改<Connector port="8080" protoc ...