文章目录

1、 CPU指令对CAS的支持(CPU的cas指令是原子的)

或许我们可能会有这样的疑问,假设存在多个线程执行CAS操作并且CAS的步骤很多,有没有可能在判断V和E相同后,正要赋值时,切换了线程,更改了值。造成了数据不一致呢?答案是否定的,因为CAS是一种系统原语,原语属于操作系统用语范畴,是由若干条指令组成的,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许被中断,也就是说CAS是一条CPU的原子指令,不会造成所谓的数据不一致问题。

2、 并发包中的原子操作类(Atomic系列)

  通过前面的分析我们已基本理解了无锁CAS的原理并对Java中的指针类Unsafe类有了比较全面的认识,下面进一步分析CAS在Java中的应用,即并发包中的原子操作类(Atomic系列),从JDK 1.5开始提供了java.util.concurrent.atomic包,在该包中提供了许多基于CAS实现的原子操作类,用法方便,性能高效,主要分以下4种类型。

  可以发现AtomicInteger原子类的内部几乎是基于前面分析过Unsafe类中的CAS相关操作的方法实现的,这也同时证明AtomicInteger是基于无锁实现的,这里重点分析自增操作实现过程,其他方法自增实现原理一样。

3、 CAS的ABA问题及其解决方案

  假设这样一种场景,当第一个线程执行CAS(V,E,U)操作,在获取到当前变量V,准备修改为新值U前,另外两个线程已连续修改了两次变量V的值,使得该值又恢复为旧值,这样的话,我们就无法正确判断这个变量是否已被修改过,如下图

这就是典型的CAS的ABA问题,一般情况这种情况发现的概率比较小,可能发生了也不会造成什么问题,比如说我们对某个做加减法,不关心数字的过程,那么发生ABA问题也没啥关系。但是在某些情况下还是需要防止的,那么该如何解决呢?在Java中解决ABA问题,我们可以使用以下两个原子类

AtomicStampedReference类

  • AtomicStampedReference原子类是一个带有时间戳的对象引用,在每次修改后,AtomicStampedReference不仅会设置新值而且还会记录更改的时间。当AtomicStampedReference设置对象值时,对象值以及时间戳都必须满足期望值才能写入成功,这也就解决了反复读写时,无法预知值是否已被修改的窘境

参考文章:

1、JAVA中的CAS

最新文章

  1. Markdown 图片助手-MarkdownPicPicker
  2. Java控制图片按比例缩放- (注意内存释放)
  3. [ASM C/C++] C语言数组
  4. json返回数据时提示字符串超出长度
  5. pig的各种运行模式与运行方式详解
  6. *HDU 1286,2824欧拉函数
  7. Spring4 + Quartz-2.2.0集成实例
  8. VC++ 动态创建单个工具条,并加载外部的位图(bmp)文件为工具栏图像
  9. 使用的组件:ckeditor
  10. 【ZOJ 3870】 Team Formation
  11. 企业网站DDOS防护解决方案
  12. SCJP_104——题目分析(1)
  13. swing常用布局
  14. java中paint repaint update 之间的关系
  15. swift新特性(__nullable和__nonnull
  16. 新手介绍简单一下iOS开发中几种界面传值
  17. js 消抖(debounce)与节流(throttle)
  18. xamarin android alertdialog详解
  19. ASP.NET Core 使用 Google 验证码(Google reCAPTCHA)
  20. 分享自己用的php分页类实例源码

热门文章

  1. Bootrap 项目实战(微金所前端首页)第三部分(CSS,js源码)
  2. MYSQL ERROR 1049 (42000): Unknown database
  3. [Ruby]Unzipping a file using rubyzip
  4. 【算法笔记】B1045 快速排序
  5. Python3 scrapy 新手命令
  6. UBoot常用命令及内核下载与引导
  7. java 接口的学习
  8. A problem has been detected and windows has been shut down to prevent damage
  9. elastic 常用操作
  10. Python openpyxl Read