V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Jacky23333
V2EX  ›  问与答

不懂就问,关于 Java 并发 CAS 的问题

  •  
  •   Jacky23333 · 2019-10-07 16:56:08 +08:00 · 981 次点击
    这是一个创建于 1655 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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 然后修改成功?

    3 条回复    2019-10-07 17:21:58 +08:00
    momocraft
        1
    momocraft  
       2019-10-07 17:03:59 +08:00
    如果这是 sun.misc.Unsafe: var2 是 obj 内的 offset, 不是比较或设置的值
    Jacky23333
        2
    Jacky23333  
    OP
       2019-10-07 17:11:31 +08:00
    @momocraft 就是 un.misc.Unsafe 这个,var2 是 obj 内的 offset 这个什么意思,不是很懂,可以说详细一点吗
    Jacky23333
        3
    Jacky23333  
    OP
       2019-10-07 17:21:58 +08:00
    @momocraft 弄懂了。谢谢老哥
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3243 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 13:30 · PVG 21:30 · LAX 06:30 · JFK 09:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.