首页
学习
活动
专区
工具
TVP
发布

Java并发编程——CAS

如果本文有错,希望在下面的留言区指正。

在之前的一些源码分析中,为了实现并发,Doug Lea 大佬在Java8及以上,大量使用了 CAS 操作。JDK 提供的关于 CAS 原子操作的类在下面工具包里面:

JDK为Java基本类型都提供了CAS工具类。

CAS

已 为例,进行分析:

如上面的源码,对于 CAS 操作,这里会出现3个值,expect、update、value。只有当expect和内存中的value相同时,才把value更新为update。

ABA 问题

假设如下事件序列:

线程 1 从内存位置V中取出A。

线程 2 从位置V中取出A。

线程 2 进行了一些操作,将B写入位置V。

线程 2 将A再次写入位置V。

线程 1 进行CAS操作,发现位置V中仍然是A,操作成功。

尽管上面的CAS操作成功了,数据也没有问题,但是程序失去了对数据变换的敏感性,不知道数据的变换。

比如发生扣款/收款行为时,应当收到短信通知这个场景,

1、时刻1 : 500元

2、时刻2:转给了 A 10 元 490 元

3、时刻3:B 转入 10 元 500 元

应当收到两条短信,而不是最后我的账户余额没有变化,就一条短信都收不到

上面的图片来源不知道是谁的,只是在一个技术群里和别人聊CAS时别人发的。

解决方法

JDK为了解决 ABA 问题,提供了两种方法

AtomicStampedReference

JDK 为了解决 ABA 问题,提供了一些方法,如 ,在版本的更新过程中,添加了一个 邮戳来标记数据的版本。

具体关于 CAS 操作源码

如上面所示,在更新的过程中,除了比较内存中value的预期值,还比较了 stamp 的预期值,只有两者都相同的时候,才会把内存中的值更新掉。

AtomicMarkableReference

和 功能相似,但 描述更加简单的是与否的关系。它的定义就是将状态戳简化为true|false。如下:

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181228G0B5X200?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券