Java里的CompareAndSet(CAS)
if (compareAndSet(current, next))
return next;
}
}
首先可以看到他是通过一个无限循环(spin)直到increment成功为止.
循环的内容是
1.取得当前值
2.计算+1后的值
3.如果当前值还有效(没有被)的话设置那个+1后的值
4.如果设置没成功(当前值已经无效了即被别的线程改过了), 再从1开始.
2. compareAndSet的实现
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
直接调用的是UnSafe这个类的compareAndSwapInt方法
全称是sun.misc.Unsafe. 这个类是Oracle(Sun)提供的实现. 可以在别的公司的JDK里就不是这个类了
3. compareAndSwapInt的实现
* Atomically update Java variable to <tt>x</tt> if it is currently
* holding <tt>expected</tt>.
* @return <tt>true</tt> if successful
*/
public final native boolean compareAndSwapInt(Object o, long offset,
int expected,
int x);
可以看到, 不是用Java实现的, 而是通过JNI调用操作系统的原生程序.
4. compareAndSwapInt的native实现
如果你下载了OpenJDK的源代码的话在hotspot\src\share\vm\prims\目录下可以找到unsafe.cpp
UnsafeWrapper("Unsafe_CompareAndSwapInt");
oop p = JNIHandles::resolve(obj);
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END
可以看到实际上调用Atomic类的cmpxchg方法.
5. Atomic的cmpxchg
这个类的实现是跟操作系统有关, 跟CPU架构也有关, 如果是windows下x86的架构
实现在hotspot\src\os_cpu\windows_x86\vm\目录的atomic_windows_x86.inline.hpp文件里
// alternative for InterlockedCompareExchange
int mp = os::is_MP();
__asm {
mov edx, dest
mov ecx, exchange_value
mov eax, compare_value
LOCK_IF_MP(mp)
cmpxchg dword ptr [edx], ecx
}
}
在这里可以看到是用嵌入的汇编实现的, 关键CPU指令是 cmpxchg
到这里没法再往下找代码了. 也就是说CAS的原子性实际上是CPU实现的. 其实在这一点上还是有排他锁的. 只是比起用synchronized, 这里的排他时间要短的多. 所以在多线程情况下性能会比较好.
代码里有个alternative for InterlockedCompareExchange
这个InterlockedCompareExchange是WINAPI里的一个函数, 做的事情和上面这段汇编是一样的
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683560%28v=vs.85%29.aspx
6. 最后再贴一下x86的cmpxchg指定
Opcode CMPXCHG
CPU: I486+
Type of Instruction: User
Instruction: CMPXCHG dest, src
Description: Compares the accumulator with dest. If equal the "dest"
is loaded with "src", otherwise the accumulator is loaded
with "dest".
Flags Affected: AF, CF, OF, PF, SF, ZF
CPU mode: RM,PM,VM,SMM
+++++++++++++++++++++++
Clocks:
CMPXCHG reg, reg 6
CMPXCHG mem, reg 7 (10 if compartion fails)
Java里的CompareAndSet(CAS)的更多相关文章
- java里的锁总结(synchronized隐式锁、Lock显式锁、volatile、CAS)
一.介绍 首先, java 的锁分为两类: 第一类是 synchronized 同步关键字,这个关键字属于隐式的锁,是 jvm 层面实现,使用的时候看不见: 第二类是在 jdk5 后增加的 Lock ...
- Java原子类中CAS的底层实现
Java原子类中CAS的底层实现 从Java到c++到汇编, 深入讲解cas的底层原理. 介绍原理前, 先来一个Demo 以AtomicBoolean类为例.先来一个调用cas的demo. 主线程在f ...
- java多线程之CAS原理
前言 在Java并发包中有这样一个包,java.util.concurrent.atomic,该包是对Java部分数据类型的原子封装,在原有数据类型的基础上,提供了原子性的操作方法,保证了线程安全.下 ...
- (转载)java高并发:CAS无锁原理及广泛应用
java高并发:CAS无锁原理及广泛应用 版权声明:本文为博主原创文章,未经博主允许不得转载,转载请注明出处. 博主博客地址是 http://blog.csdn.net/liubenlong007 ...
- paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)
paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象) 1 锁的缺点 2 CAS(Compare ...
- Java并发编程之CAS
CAS(Compare and swap)比较和替换是设计并发算法时用到的一种技术.简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替 ...
- Java高性能编程之CAS与ABA及解决方法
Java高性能编程之CAS与ABA及解决方法 前言 如果喜欢暗色调的界面或者想换换界面,可以看看我在个人博客发布的 Java高性能编程之CAS与ABA及解决方法. CAS概念 CAS,全称Compar ...
- Java并发编程之CAS二源码追根溯源
Java并发编程之CAS二源码追根溯源 在上一篇文章中,我们知道了什么是CAS以及CAS的执行流程,在本篇文章中,我们将跟着源码一步一步的查看CAS最底层实现原理. 本篇是<凯哥(凯哥Java: ...
- Java并发编程之CAS第三篇-CAS的缺点及解决办法
Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...
随机推荐
- javascript获取日期的年,月,日
var date = new Date(strTime); return date.getFullYear()+"-"+(date.getMonth()+1)+"-&qu ...
- android adt 最新下载地址
打开这个网址就可以看到adt的详细信息: http://developer.android.com/sdk/installing/installing-adt.html 或者直接在你的eclipse ...
- unity, windows: Unhandled Exception: System.UnauthorizedAccessException: Access to the path "XXX\Temp\Assembly-CSharp.dll.mdb" is denied
的windows上使用unity,修改过脚本或inspector中的数值后运行编辑器报错: Unhandled Exception: System.UnauthorizedAccessExceptio ...
- MySql(零):Linux(CentOS7)下安装和配置MySQL5.7.20(安装包安装)
一.下载安装包 1.在官网下载MySQL5.7安装包 mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz. 下载地址:https://dev.mysql.com/do ...
- web info
http://blog.csdn.net/qq_24473141/article/details/51363662 http://blog.sina.com.cn/s/blog_8e392fc2010 ...
- Django中的request对象组成
if request.REQUEST.has_key('键值'): HttpRequest对象的属性 参考: 表 H-1. HttpRequest对象的属性 属 性 描述 path 表示提 ...
- java获取真实的ip地址
直接上代码,获取请求主机的IP地址,如果通过代理进来,则透过防火墙获取真实IP地址 public class IPUtil { private static final Logger logger = ...
- 关于Python的Object继承
今天在Coding的使用,使用了python的单例模式,发现了一个很有趣的问题. class x(object): __se = None a = None def __new__(cls): if ...
- Time Limit Exceeded 求逆序对数。
/** 题目:Time Limit Exceeded 链接:https://oj.ejq.me/problem/28 题意:求逆序对数. 思路:树状数组求逆序对数.维护前面有多少个<=当前数的数 ...
- Java基础04 封装与接口(转载)
数据成员和方法都是同时开放给内部和外部的.在对象内部,我们利用this来调用对象的数据成员和方法.在对象外部,比如当我们在另一个类中调用对象的时,可以使用 对象.数据成员 和 对象.方法() 来调用对 ...