Java并发的CAS原理与ABA问题的讲解

2025-05-29 0 60

cas原理

在计算机科学中,比较和交换(compare and swap)是用于实现多线程同步的原子指令。 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。 这是作为单个原子操作完成的。 原子性保证新值基于最新信息计算; 如果该值在同一时间被另一个线程更新,则写入将失败。 操作结果必须说明是否进行替换; 这可以通过一个简单的布尔响应(这个变体通常称为比较和设置),或通过返回从内存位置读取的值来完成(摘自维基本科)

cas流程

Java并发的CAS原理与ABA问题的讲解

以atomicinteger.addandget()为例讲解cas

javadoc

public final int addandget​(int delta)
atomically adds the given value to the current value, with memory effects as specified by varhandle.getandadd(java.lang.object…).
parameters:
delta – the value to add
returns:
the updated value

在java的源码中

?

1

2

3
public final int addandget(int delta) {

return u.getandaddint(this, value, delta) + delta;

}

这里的value是在该类初始化的时候获取到的,理解一下就是这时候我们调用unsafe的objectfieldoffset从atomic类文件中获取value的偏移量,那么value其实就是记录value的偏移量的。

value准确的是value这个字段相对与atomicinteger这个对象内存起始地址的偏移量,由于这个方法的最底层是jni调用native的方法,所以需要传入这个值。

?

1
private static final long value = u.objectfieldoffset(atomicinteger.class, "value");

继续往下执行:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
/**

* atomically adds the given value to the current value of a field

* or array element within the given object {@code o}

* at the given {@code offset}.

* @param o object/array to update the field/element in

* @param offset field/element offset

* @param delta the value to add

* @return the previous value

* @since 1.8

**/

@hotspotintrinsiccandidate

public final int getandaddint(object o, long offset, int delta) {

int v;

do {

v = getintvolatile(o, offset);

} while (!weakcompareandsetint(o, offset, v, v + delta));

return v;

}

?

1

2

3

4

5

6
@hotspotintrinsiccandidate

public final boolean weakcompareandsetint(object o, long offset,

int expected,

int x) {

return compareandsetint(o, offset, expected, x);

}

如果obj内的value和expect相等,就证明没有其他线程改变过这个变量,那么就更新它为update,如果这一步的cas没有成功,那就采用自旋的方式继续进行cas操作。从代码中看着也是两个步骤,但其实在jni里是借助于一个cpu指令完成的,实际还是原子操作。

aba问题

产生aba问题的原因

cas需要在操作值的时候检查下值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是a,变成了b,又变成了a,那么使用cas进行检查时会发现它的值没有发生变化,但是实际上却变化了。这就是cas的aba问题。

如何规避aba问题

常用的办法是在更新数据的时候加入版本号,以版本号来控制更新。

Java并发的CAS原理与ABA问题的讲解

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对快网idc的支持。如果你想了解更多相关内容请查看下面相关链接

原文链接:https://blog.csdn.net/u012449363/article/details/86549823

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Java并发的CAS原理与ABA问题的讲解 https://www.kuaiidc.com/110157.html

相关文章

发表评论
暂无评论