CAS问题
来源:3-2 线程安全性-原子性-atomic-2
慕码人1464173
2019-01-31
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
// var5主内存中的值,var1是线程工作内存中的值
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
var5主内存中的值,var1是线程工作内存中的值,比较的是var1.value和var5是否相同,不同继续获取主内存中的值与线程工作内存中的值比较。问题:假设var1是3,主内存中的值被其他线程操作自增变为4,5,6 … 这边是不是会一直循环下去,直到主内存中的值同步到线程工作内存中,且没有其他线程操作?还是说这里面哪一步是有同步工作内存和主内存的操作?
2回答
-
Jimin
2019-01-31
继续看 compareAndSwapInt(obj, offset, expect, update)能清楚一些,如果obj内的value和expect相等,就证明没有其他线程改变过这个变量,那么就更新它为update,如果不相等返回false,调用getIntVolatile获取内存里最新的值给expect的,之后函数里的update也跟着变了,再去尝试cas更新,只要这两步过程中没其他线程操作,就会或许成功,极端情况下就是这两步过程中有其他操作,需要再重试一次。因为每次是取最新值去尝试,cas处理时只要和内存一致就更新,其实并不会出现无限循环,并发很高时也会很快结束
022019-02-01 -
Jimin
2019-01-31
你好,这篇手记 https://www.imooc.com/article/25277 我做了一些问题的整理,包括cas,你这个我单独复制出来:
关于CAS中compareAndSwapInt(var1, var2, var5, var5 + var4)的理解
compareAndSwapInt(var1, var2, var5, var5 + var4)换成 compareAndSwapInt(obj, offset, expect, update)能清楚一些,如果obj内的value和expect相等,就证明没有其他线程改变过这个变量,那么就更新它为update,如果这一步CAS没有成功,那就采用自旋的方式继续进行CAS操作。这块是一个CPU指令完成的,依旧是原子操作。
继续回答一下你的疑问。这里不会出现死循环。因为对比和更新的操作是通过一条cpu指令执行的,如果期望值检查通过更新了的话会返回true,循环就直接退出了。如果期望值检查不通过没更新会返回false,这是更新期望值为最新的值,再尝试更新,直到返回true。
上面的代码里getIntVolatile会强制去内存中获取最新的数据012019-01-31
相似问题