CAS 理解以及总结

徘徊边缘 提交于 2020-04-27 02:21:15

简介

CAS(compare and swap) 即“比较”和“交换”,主要为了解决在多线程并发情况下,使用锁造成的性能消耗问题。在高效、不加锁的情况下,能够以原子性的行为实现数据的操作。一般系统层面都在硬件层次上直接支持CAS指令,而高级语言一般都会直接利用这些指令。

java中的CAS

java.util.concureent.atomic包中拥有大量的原子类,他们都是利用了CAS来完成原子性操作。需要关注的就是它们共同都拥有的一个函数compareAndSet(expect,update)

 public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

AtomicInteger类中的compareAndSet函数为例,其他各个原子类的compareAndSet函数差异不大。最后调用的都是unsafe.compareAndSwapInt函数或者unsafe.compareAndSwapObject只不过一个是数值一个是引用类型而已。

compareAndSet函数

这个函数总共有两个参数,expectupdate,第一个代表期望值,第二个代表要更新的值。当在更新值时,如果当前的值和期望值相同则进行更新,否则不更新。

比较

synchronized想比较,这种原子性的更新方式是另外一种思维。synchronized是悲观的,它认为在它操作时,极大可能产生冲突,所以先获取锁,让别人无法操作后才进行操作。这种阻塞算法式的方式,的开销是比较大的,它在得不到锁是,需要进入等待锁的Lock池,一直等待其他线程的唤醒,有上下文切换的开销。

而CAS是一种乐观的方式,它假定产生冲突的几率较小。如果发生冲突也没关系,继续尝试就可以。它是非阻塞的,所有有着比synchronized更高的效率,且性能更高。

ABA问题

使用CAS方式更新,会产生一个ABA的问题。ABA是指,两个线程AB,当B将值修改后又修改回原来的值时,A线程是无法感知到数据是否发生过变化。要解决这个问题,可以使用AtomicStampedReference来解决,在修改数据时,了外附加一个时间戳,只有时间戳和数据都相同时才会进行更改。

AtomicStampedReference

暂留

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!