加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

CAS并发、ABA问题的解决、实现无锁队列

(2017-10-31 21:48:57)
标签:

it

本文是我通过对CAS相关博客的学习后自己的总结,如有错误请及时提出噢 

首先从三个问题出发:
 1、CAS如何提升自减和自增操作的并发效率
 2、CAS遇到ABA问题如何解决 
 3、通过CAS如何实现一个无锁队列  

CAS(Compare-and-Swap):实现了Check-and-Set原子操作功能;代表一种原子操作,是一种系统原语,原语的执行必须是连续的,在执行过程中不允许被中断。 
---------------------------------------------------------------------------------------- 
问题一:CAS如何提升自减和自增操作的并发效率 
CAS类似乐观锁,有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
 程序员可通过这种乐观锁的机制实现自减和自增操作的高并发效率。

问题二:CAS遇到ABA问题如何解决 
所谓ABA问题是在进行CAS操作的时候,因为在更改V之前,CAS主要询问“V的值是否仍然为A”,所以在第一次读取V之后以及对V执行CAS操作之前,如果先将值从A改为B,然后再改回A,这时CAS的询问仍然成立,则CAS操作会成功。
 
  解决方案:
 第一种:通常是采用CAS的一个变种DCAS,DCAS是对于每一个V增加一个引用的表示修改次数的标记符。对于每个V,如果引用修改了一次,这个计数器就加1,然后再这个变量需要更新的时候,就同时检查变量的值和计数器的值。都符合条件才可以修改V值。
 第二种:通常通过将标记或版本编号与要进行CAS操作的每个值相关联,并原子地更新值和标记。也就是一旦V第一次被使用,就不会再重复使用,如有需要则分配新的V。垃圾收集器可以检查V,保证其不被循环使用,直到当前的访问操作全部结束。

问题三:通过CAS如何实现一个无锁队列
分析参考了博文:无锁队列的实现

首先,进行队列的入队操作
通过CAS(V,A,B)的判断当尾结点的next不为NULL,则一直将p更新为尾结点,这一操作是可能有在我还有没有插入成功时别的线程已经先我一步插入了尾结点,这样判断则不成立,会一直更新p,直到p->next为NULL,才进行插入。

这样还有一个隐藏的问题:当我们线程在执行操作时,突然停掉或者挂掉,那么线程会进入死循环,要怎么办呢,所以有了如下的改进方法

在进入循环后若p不是尾结点,则让他自己走到尾结点的位置,可以预防当前线程已经挂掉的现象。














0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有