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原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...
随机推荐
- C++/C混合编程
C与C++混合编程 C++ 是在 C 语言的基础上发展起来的.在某种程度上,我们可将 C++ 看做 C 的一种扩展.在本质上,二者的数据类型和函数调用惯例都是一致的,因此 C 与 C++ 混合编译也是 ...
- CentOS6.5下docker的安装及遇到的问题和简单使用(已实践)
转载自 CentOS6下docker的安装和使用 Docker是一个开源的应用容器引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.利用Linux的LXC.AUFS. Go语言.c ...
- MATLAB 的字符串分析
MATLAB的字符串分析. 字符串实际上是指1Xn 的字符数组. MATLAB软件具有强大的字符串处理功能,提供了很多的字符或字符串处理函数,包括字符串的创建.字符串的属性.比较.查找以及字符串的转换 ...
- MVC中上传文件大小限制的解决办法
在Web.Config文件中配置限制上传文件大小与时间. 需要在配置文件里面设置文件上传限定的两个属性值:maxAllowedContentLength,maxRequestLength 允许上传文件 ...
- 在 .NET 4.0 下编写扩展代码以支持 async 异步编程
微软在C# 5中引入了async.await这两个异步编程的关键字,要使用这两个关键字需要你的IDE支持C#5.0语法,也就意味着你需要使用VS 2012版本以上IDE,或者在Vs2010卸载其编译器 ...
- MySQL学习总结(一)下载与安装
关于数据库这块平时用的也就是Oracle和SQL Server,关于别的数据库也就是耳闻,但从没有用过.所以,最近一直都在学习使用MySQL数据库,这个教程也是通过记录博客,增加学习的印象. 关于My ...
- 转MQTT SERVER 性能测试报告
硬件环境: 内存4G CPU4核 SERVER及端口: apollo端口 61619 mosquitto:端口 1884 activeMQ端口:1883 emqtt 端口1885 测试方法 并发测试: ...
- Codeforces Round #240 (Div. 1)B---Mashmokh and ACM(水dp)
Mashmokh's boss, Bimokh, didn't like Mashmokh. So he fired him. Mashmokh decided to go to university ...
- CAN总线过滤规则
奇怪的设计 If (AFMR & Message_ID) == (AFMR & AFIR) then Capture Message AFIR 1 接收 AFMR 0 接收 设置某接收 ...
- 自己实现strcpy函数
#include //printf #include //ssert #include //malloc #include //strlen char * sstrcpy(char * strdst, ...