public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
最近在看 JAVA 并发 CAS 的内容,看了源码之后不是很理解为什么它可以实现线程安全。
首先 var2 是对象在该线程里面的值,var5 是内存里面实际的值。compareAndSwapInt 只有在对比 var2 和 var5 相等的情况下才会将 var5+var4 的值更新到 var2 上面去。如果不相等则继续循环。
那现在的问题就是假设在进程 A 里面如果当 var2 等于 10 的时候,另外一个进程将新的值 20 写进内存中。那么此时 A 进程调用这个方法发现 var2=10 var5=20 两个值不相等那么继续循环。那么这种情况下什么时候才会跳出循环。无论怎么获取,getIntVolatile()得到的值永远都是 20 而 var2 的值永远都是 10,这样不是永远都不会相等吗?
第二个问题,有没有可能 A 进程里执行完 var5 = this.getIntVolatile(var1, var2);这句语句的时候,另外一个进程就把内存里面的值修改了。导致 var5 获得的值是个错误的值,但是 A 线程就拿着这个值去调用 compareAndSwapInt 方法,然后 var2 等于 var5 然后修改成功?
1
momocraft 2019-10-07 17:03:59 +08:00
如果这是 sun.misc.Unsafe: var2 是 obj 内的 offset, 不是比较或设置的值
|
2
Jacky23333 OP @momocraft 就是 un.misc.Unsafe 这个,var2 是 obj 内的 offset 这个什么意思,不是很懂,可以说详细一点吗
|
3
Jacky23333 OP @momocraft 弄懂了。谢谢老哥
|