CAS

来源:互联网 发布:中国人种基因知乎 编辑:程序博客网 时间:2024/05/17 04:56

概念与基本原理

CAS 全名叫Compare And Swap 即比较并交换 。CAS方法包含三个操作数(内存地址,预期值,新值)当内存地址中的值与预期值相符,则将内存地址中的值替换为新值。在多线程的情况中,CAS实现了自旋锁,CPU给CAS一定的时间,在这段时间内,如果符合条件则执行程序,否则放弃。
* CAS是原子性的 *

Java中的CAS

Java利用CPU的CAS指令,同时借助JNI来完成Java的非阻塞算法。其他的原子操作都是利用类似的特性完成的。而整个J.U.C都是建立在CAS之上的,因此synchronized阻塞算法,J.U.C在性能上有了很大的提升。

/** * this: 对象 * valueOffset:偏移量 * expect:预期值 * update:新值 * this+valueOffset能定位到内存地址 */sun.unsafe.compareAndSwapInt(this, valueOffset, expect, update);类似:if (this == expect) {  this = update return true;} else {return false;}

CAS的缺点

1、ABA问题

问题:因为CAS在操作值时检查值是否发生变化,如果没有则操作。如果将一个值从A改成B,有从B改成A,那么使用CAS检查时会发现值没变,而实际上值改变了。
解决:CAS每次更改值时,添加一个版本号,每次更改是还应该检查版本号是否正确

2、循环时间大

问题:如果自旋锁CAS长时间不成功的话会对CPU造成很大的压力
解决:如果JVM支持处理器提供的pause效率会有一定的提升。pause有两个功能,第一:延迟流水线的指令,使CPU不会过多的消耗执行资源,第二:可以避免在退出循环时,因内存顺序冲突,引起CPU流水被清空,提高CPU的效率。

3、只能保证一个变量的原子性

问题:当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作,但是对多个共享变量操作时,循环CAS就无法保证操作的原子性
解决:JDK1.5后可以使用AtomicReference类来保证引用对象之间的原子性,可以将多个变量放到一个对象中使用CAS操作。

原创粉丝点击