建筑网站源码,中国互联网协会秘书长,万网域名注册教程,苏州高端网站制作机构1. 定义
CAS是Compare And Swap的缩写#xff0c;直译就是比较并交换。CAS是现代CPU广泛支持的一种对内存中的共享数据进行操作的一种特殊指令#xff0c;这个指令会对内存中的共享数据做原子的读写操作。其作用是让CPU比较内存中某个值是否和预期的值相同#xff0c;如果相…1. 定义
CAS是Compare And Swap的缩写直译就是比较并交换。CAS是现代CPU广泛支持的一种对内存中的共享数据进行操作的一种特殊指令这个指令会对内存中的共享数据做原子的读写操作。其作用是让CPU比较内存中某个值是否和预期的值相同如果相同则将这个值更新为新值不相同则不做更新。 本质上来讲CAS是一种无锁的解决方案也是一种基于乐观锁的操作可以保证在多线程并发中保障共享资源的原子性操作相对于信号量或锁来说是一种轻量级的实现方案。 在上图中涉及到三个值的比较和操作修改之前获取的待修改值A业务逻辑计算的新值B以及待修改值对应的内存位置的C。 整个处理流程中假设内存中存在一个变量i它在内存中对应的值是A第一次读取此时经过业务处理之后要把它更新成B那么在更新之前会再读取一下i现在的值C如果在业务处理的过程中i的值并没有发生变化也就是A和C相同才会把i更新交换为新值B。如果A和C不相同那说明在业务计算时i的值发生了变化则不更新交换成B。最后CPU会将旧的数值返回。而上述的一系列操作由CPU指令来保证是原子的。
2. CAS的内核实现
s64 generic_atomic64_cmpxchg(atomic64_t *v, s64 o, s64 n)
{unsigned long flags;raw_spinlock_t *lock lock_addr(v);s64 val;raw_spin_lock_irqsave(lock, flags);val v-counter;if (val o)v-counter n;raw_spin_unlock_irqrestore(lock, flags);return val;
}3. CAS存在的问题
3.1 ABA问题
虽然使用CAS可以实现非阻塞式的原子性操作但是会产生ABA问题ABA问题出现的基本流程 ● 进程P1在共享变量中读到值为A ● P1被抢占了进程P2执行 ● P2把共享变量里的值从A改成了B再改回到A此时被P1抢占 ● P1回来看到共享变量里的值没有被改变于是继续执行 虽然P1以为变量值没有改变继续执行了但是这个会引发一些潜在的问题。ABA问题最容易发生在lock free的算法中的CAS首当其冲因为CAS判断的是指针的地址。如果这个地址被重用了呢问题就很大了地址被重用是很经常发生的一个内存分配后释放了再分配很有可能还是原来的地址。 维基百科上给了一个形象的例子你拿着一个装满钱的手提箱在飞机场此时过来了一个火辣性感的美女然后她很暖昧地挑逗着你并趁你不注意把用一个一模一样的手提箱和你那装满钱的箱子调了个包然后就离开了你看到你的手提箱还在那于是就提着手提箱去赶飞机去了。 ABA问题的解决思路就是使用版本号在变量前面追加上版本号每次变量更新的时候把版本号加1那么A-B-A就会变成1A-2B-3A。
3.2 循环时间太长
如果CAS一直不成功呢这种情况绝对有可能发生如果自旋CAS长时间地不成功则会给CPU带来非常大的开销。在JUC中有些地方就限制了CAS自旋的次数例如BlockingQueue的SynchronousQueue。
3.3 只能保证一个共享变量的原子性
看了CAS的实现就知道这只能针对一个共享变量如果是多个共享变量就只能使用锁了当然如果你有办法把多个变量整成一个变量利用CAS也不错。从Java1.5开始JDK提供了AtomicReference类来保证引用对象之间的原子性你可以把多个变量放在一个对象里来进行CAS操作。