当前位置: 首页 > 面试题库 >

AtomicInteger类中addAndGet的实现

陈哲
2023-03-14
问题内容

我正在遍历该类中addAndGet方法的Java(Java 6)源代码AtomicInteger

相应的代码如下:

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

compareAndSet方法调用一个本地方法来执行分配。主要有两个问题:

  1. 无限循环有何帮助?
  2. 在“ if(compareAndSet(current,next))”条件下可能返回false的情况是什么?在这种情况下,代码可能会陷入无限循环。如果可以保证compareAndSet总是返回“ true”,那么我们是否可以完全取消此检查?

类似的质疑是与decrementAndGetgetAndDecrementgetAndAdd方法为好。


问题答案:

无限循环有何帮助?

这意味着:重试直到成功。如果没有循环,则第一次可能不会成功(请参阅下文)。

在“ if(compareAndSet(current,next))”条件下可能返回false的情况是什么?

如果两个线程试图同时修改该值,则会发生这种情况。其中一个将首先到达那里。另一个将失败。

想象两个线程(A和B)试图从5递增到6

A: int current = get();  // current = 5
B: int current = get();  // current = 5
B: int next = current + delta;  // next = 6
B: if (compareAndSet(current, next))  // OK
          return next;
A: int next = current + delta;  // next = 6 
A: if (compareAndSet(current, next))  
    // fails, because "current" is still 5
    // and that does not match the value which has been changed to 6 by B

请注意,此类的重点是避免锁。因此,您具有这种“乐观的货币控制”:只需假设没有其他人同时在处理数据,并且如果发现这是错误的,请回滚并重试。

在这种情况下,代码可能会陷入无限循环

并不是的。对于每一个对值有作用的线程,它只能失败一次。

在第二次迭代中从上方线程A:

A: int current = get();  => current now 6
A: int next = current + delta;  => next = 7
A: if (compareAndSet(current, next))  => now OK

可以想象,如果其他线程不断地更新该值,那么一个线程将永远等待,直到那时。为了避免这种情况,您需要对“公平”进行一些定义(并发包中的其他一些工具也支持)。



 类似资料:
  • 问题内容: AtomicInteger的getAndIncrement实现执行以下操作: 它不等于aVolatileVariable ++吗?(我们知道这是不正确的用法)。没有同步,我们如何确保此完整操作是原子的?如果在步骤1中读取了变量“ current”后,volatile变量的值发生了变化,该怎么办? 问题答案: “秘密调味料”在此调用中: 如果在读取 后 同时更改了原始易失性值,则该操作将

  • java.util.concurrent.atomic.AtomicInteger类提供对底层int值的操作,可以原子方式读取和写入,还包含高级原子操作。 AtomicInteger支持底层int变量的原子操作。 它具有get和set方法,类似于对volatile变量的读写操作。 也就是说,集合与同一变量上的任何后续获取具有先发生关系。 原子compareAndSet方法也具有这些内存一致性功能。

  • 问题内容: 我有点理解AtomicInteger和其他Atomic变量允许并发访问。但是在什么情况下通常使用此类? 问题答案: 有两个主要用途: 作为可以同时被多个线程使用的原子计数器(,等) 作为支持比较和交换指令()来实现非阻塞算法的原语。 这是BrianGöetz的中的非阻塞随机数生成器的示例: 如你所见,它的工作原理与几乎相同incrementAndGet(),但是执行任意计算(calcu

  • 在AtomicInteger类的getAndIncrement方法中,调用了unsafe类的getAndAddInt方法,该方法包含compareAndSwapInt方法和自旋(Do...While)。compareAndSwapInt方法是线程安全的,那么为什么不只是更改compareAndSwapInt方法中的值,还需要旋转是安全的呢?谢谢你的回答。

  • 问题内容: 我试图在注入控制器的单例spring服务中实现ConcurentHashMap的线程安全用法: 有没有更好的方法可以使哈希映射成为线程安全的?我如何才能使其适应集群环境?这是我的另一个问题。 问题答案: 我的目的不是要回答这个问题,特别是。因为我没有多方面的专业知识;但是,我想指出我认为值得注意的地方。 @JB Nizet在评论之一中提到该代码是 线程安全的 和 正确的 。我想根据Ja

  • 本文向大家介绍讲讲 AtomicInteger 的使用?相关面试题,主要包含被问及讲讲 AtomicInteger 的使用?时的应答技巧和注意事项,需要的朋友参考一下