CAS 原理
Compare and Swap,解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS操作包含三个操作数——内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在CAS指令之前返回该位置的值。CAS有效地说明了“我认为位置V应该包含值A;如果包含该值,则将B放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。
当同时存在读写线程时,默认情况下是不保证线程安全的,因而需要利用信号量来进行线程同步(Synchronization),如关键代码段、互斥体等, 同时操作系统也提供了相应的API。然而同步并不总是满足条件的且有效率的,比如陷入内核时会有性能损失、死锁、活锁以及资源浪费等。
有啥用处?
对于常用多线程编程的人估计知道,对于一般人估计都不曾听说。在jdk5之前,我们知道,在多线程编程的时候,为了保证多个线程对一个对象同时进行访问时,我们需要加同步锁synchronized,保证对象的在使用时的正确性,但是加锁的机制会导致如下几个问题
1.加多线程竞争下,加锁和释放锁会导致较多的上下文切换,引起性能问题。
2.多线程可以导致死锁的问题。
3.多线程持有的锁会导致其他需要此锁的线程挂起。
4……
有更好的办法么?
锁的分类:独占锁(悲观锁),乐观锁
独占锁:synchronized就是一种独占锁,它会导致所有需要此锁的线程挂起,等待锁的释放。
乐观锁:每次不加锁去完成操作,如果因为冲突失败就重试,直到成功。
CAS的机制就相当于这种(非阻塞算法),CAS是由CPU硬件实现,所以执行相当快.CAS有三个操作参数:内存地址,期望值,要修改的新值,当期望值和内存当中的值进行比较不相等的时候,表示内存中的值已经被别线程改动过,这时候失败返回,当相等的时候,将内存中的值改为新的值,并返回成功。
在 java.util.concurrent.atomic包中可以查看源代码的实现,这里参java.util.concurrent.atomic.AtomicLong源代码,贴出核心代码:
//+1操作 public final long getAndIncrement() { while (true) { long current = get(); long next = current + 1; //当+1操作成功的时候直接返回,退出此循环 if (compareAndSet(current, next)) return current; } } //调用JNI实现CAS public final boolean compareAndSet(long expect, long update) { return unsafe.compareAndSwapLong(this, valueOffset, expect, update); }
转载请注明:前端收藏 » CAS(Compare and Swap)分析理解