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

如何理解 AtomicInteger 里的 CAS 操作?

  •  
  •   esolve · 2017-04-02 17:15:12 +08:00 · 1542 次点击
    这是一个创建于 2607 天前的主题,其中的信息可能已经有所发展或是发生改变。
    为何要循环直到成功?如果这期间有另外的线程更改了 value ,导致 compareAndSet ()返回 false ,那这就表面已经不是原子性了吧,还继续重复有啥意义?


    public final int getAndIncrement() {
    for (;;) {
    int current = get();
    int next = current + 1;
    if (compareAndSet(current, next))
    return current;
    }
    }

    为何要循环直到成功?如果这期间有另外的线程更改了 value ,导致 compareAndSet ()返回 false ,那这就表面已经不是原子性了吧,还继续重复有啥意义?
    6 条回复    2017-04-02 23:42:46 +08:00
    kaneg
        1
    kaneg  
       2017-04-02 18:07:23 +08:00 via iPhone
    因为 cas 是原子的,所以返回 true 就证明原子操作成功,该循环退出。若 cas 操作失败,说明被其他线程抢先,则继续循环,直到 cas 成功。

    用一句话总结就是:宏观的原子性操作是由无数的 cas 原子操作失败换来的唯一一次成功。
    honeycomb
        2
    honeycomb  
       2017-04-02 18:18:07 +08:00 via Android
    因为它的目的是要自增 1 ,且不需要保证调用它的线程的顺序:

    一群线程在竞争这个原子变量时,对于线程 A ,它的一次操作对应于 current 为 1 时自增到 2 是可以的,如果被另一个线程抢先的话, A 等下一个循环,从 2 自增到 3 也是可以的。

    从计数的角度来如此更换一下顺序不影响结果。

    如果竞争非常激烈,这样的乐观锁的性能不一定会比悲观锁性能好。
    esolve
        3
    esolve  
    OP
       2017-04-02 18:50:52 +08:00
    @kaneg 被其他线程抢先了,那还干嘛继续循环?
    譬如我现在 AtomicInteger 的值是 4,我期望其自赠变成 5
    但是被其他线程抢先了
    那我就应该放弃这次自赠啊
    如果想继续,那就再调用一下 getAndIncrement 啊
    esolve
        4
    esolve  
    OP
       2017-04-02 22:17:23 +08:00
    dingdingding
    slixurd
        5
    slixurd  
       2017-04-02 22:38:58 +08:00   ❤️ 1
    @esolve 因为你理解的作用不对....
    原始值是 4,他能保证执行了 2 次 getAndIncrement 结果一定是 6 的...
    wwqgtxx
        6
    wwqgtxx  
       2017-04-02 23:42:46 +08:00 via iPhone
    你要执行的是把一个变量+1 这个操作,而不是保证一定是访问的瞬间值+1 这个操作,所以如果同时有 n 个线程调用 getAndIncrement ,最后的结果应该是原始值+n 而不是原始值+1
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3377 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 04:12 · PVG 12:12 · LAX 21:12 · JFK 00:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.