Java CAS总结
文章目录
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设置对象值时,对象值以及时间戳都必须满足期望值才能写入成功,这也就解决了反复读写时,无法预知值是否已被修改的窘境
参考文章:
最新文章
- Markdown 图片助手-MarkdownPicPicker
- Java控制图片按比例缩放- (注意内存释放)
- [ASM C/C++] C语言数组
- json返回数据时提示字符串超出长度
- pig的各种运行模式与运行方式详解
- *HDU 1286,2824欧拉函数
- Spring4 + Quartz-2.2.0集成实例
- VC++ 动态创建单个工具条,并加载外部的位图(bmp)文件为工具栏图像
- 使用的组件:ckeditor
- 【ZOJ 3870】 Team Formation
- 企业网站DDOS防护解决方案
- SCJP_104——题目分析(1)
- swing常用布局
- java中paint repaint update 之间的关系
- swift新特性(__nullable和__nonnull
- 新手介绍简单一下iOS开发中几种界面传值
- js 消抖(debounce)与节流(throttle)
- xamarin android alertdialog详解
- ASP.NET Core 使用 Google 验证码(Google reCAPTCHA)
- 分享自己用的php分页类实例源码
热门文章
- Bootrap 项目实战(微金所前端首页)第三部分(CSS,js源码)
- MYSQL ERROR 1049 (42000): Unknown database
- [Ruby]Unzipping a file using rubyzip
- 【算法笔记】B1045 快速排序
- Python3 scrapy 新手命令
- UBoot常用命令及内核下载与引导
- java 接口的学习
- A problem has been detected and windows has been shut down to prevent damage
- elastic 常用操作
- Python openpyxl Read