Jacky23333
V2EX  ›  问与答

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

  •  
  •   Jacky23333 · Oct 7, 2019 · 1388 views
    This topic created in 2423 days ago, the information mentioned may be changed or developed.
    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 replies    2019-10-07 17:21:58 +08:00
    momocraft
        1
    momocraft  
       Oct 7, 2019
    如果这是 sun.misc.Unsafe: var2 是 obj 内的 offset, 不是比较或设置的值
    Jacky23333
        2
    Jacky23333  
    OP
       Oct 7, 2019
    @momocraft 就是 un.misc.Unsafe 这个,var2 是 obj 内的 offset 这个什么意思,不是很懂,可以说详细一点吗
    Jacky23333
        3
    Jacky23333  
    OP
       Oct 7, 2019
    @momocraft 弄懂了。谢谢老哥
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2977 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 15:00 · PVG 23:00 · LAX 08:00 · JFK 11:00
    ♥ Do have faith in what you're doing.