CAS原理分析
2016-07-25 16:13
309 查看
CAS
CAS:Compare and Swap, 翻译成比较并交换。
在java.util.concurrent大量使用了CAS算法来实现非阻塞并发。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。
当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。下面看下Java并发包中的原子类是如何实现。
在这里采用了CAS操作,每次从内存中读取数据然后将此数据和+1后的结果进行CAS操作,如果成功就返回结果,否则重试直到成功为止。
而compareAndSet利用JNI来完成CPU指令的操作.整体的过程就是这样子的,利用CPU的CAS指令,同时借助JNI来完成Java的非阻塞算法。
其它原子操作都是利用类似的特性完成的,其中unsafe.compareAndSwapInt(this, valueOffset, expect, update);是Unsafe中的一个Native方法。
可以看出,到此为止与Java实现相关的都到这里结束了。下面看看这个Native方法,该方法底层是用C++实现:
这里实际调用的是cmpxchg(x, addr, e),这个函数涉及到了Cpu架构指令,网上找了这个函数的代码,可以看出在这个函数中已近嵌入了汇编代码了,也就是说CAS是在CPU指令级别实现的。
CAS虽然能够实现高效并发,而且JDK并发包中很多类都使用了CAS来实现非阻塞并发,CAS也是有一定的缺点,常见的ABA问题已经可以通过版本号来解决,但是如果CAS一直不成功
那么将会严重耗费CPU资源。
(完)
CAS:Compare and Swap, 翻译成比较并交换。
在java.util.concurrent大量使用了CAS算法来实现非阻塞并发。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。
当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。下面看下Java并发包中的原子类是如何实现。
private volatile int value; public final int get() { return value; } * Atomically sets to the given value and returns the old value. * * @param newValue the new value * @return the previous value */ public final int getAndSet(int newValue) { for (;;) { int current = get(); if (compareAndSet(current, newValue)) return current; } } public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } compareAndSet(int expect, int update),
在这里采用了CAS操作,每次从内存中读取数据然后将此数据和+1后的结果进行CAS操作,如果成功就返回结果,否则重试直到成功为止。
而compareAndSet利用JNI来完成CPU指令的操作.整体的过程就是这样子的,利用CPU的CAS指令,同时借助JNI来完成Java的非阻塞算法。
其它原子操作都是利用类似的特性完成的,其中unsafe.compareAndSwapInt(this, valueOffset, expect, update);是Unsafe中的一个Native方法。
可以看出,到此为止与Java实现相关的都到这里结束了。下面看看这个Native方法,该方法底层是用C++实现:
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) 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
这里实际调用的是cmpxchg(x, addr, e),这个函数涉及到了Cpu架构指令,网上找了这个函数的代码,可以看出在这个函数中已近嵌入了汇编代码了,也就是说CAS是在CPU指令级别实现的。
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { // 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 } }
CAS虽然能够实现高效并发,而且JDK并发包中很多类都使用了CAS来实现非阻塞并发,CAS也是有一定的缺点,常见的ABA问题已经可以通过版本号来解决,但是如果CAS一直不成功
那么将会严重耗费CPU资源。
(完)
相关文章推荐
- Centos Tomcat 清楚默认首页
- Redis 高级: Redis 双击热备之 sentinel
- AFNetworkReachabilityManager检测网络状态
- iOS中数据持久化
- 《java多线程编程核心技术》核心笔记(三) Lock的使用
- Develop>API Guides>Introduction>Device Compatibility 中文翻译
- UI系统技巧——制作血条与雷达图
- 设置页面停留时间
- 基于Redis的分布式锁实现方式
- ring buffer api(可循环读写)
- HDU - 1702 ACboy needs your help again!
- 从技术角度上来说Android 防杀方法(应用进程守护)
- CURL模拟登录
- 618淘宝应用小谈
- Verilog基础知识12(华为verilog典型电路设计--附件有源码 )
- Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
- 【转载】jQuery动画中的queue()函数
- spring 学习笔记
- 5. Longest Palindromic Substring
- Android Studio关于SVN的相关配置及从SVN检出项目