AtomicInteger类中addAndGet的实现 [英] Implementation of the addAndGet in AtomicInteger class

查看:419
本文介绍了AtomicInteger类中addAndGet的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I was going through the Java(Java 6) souce code for the addAndGet method in the AtomicInteger class.

相应的代码如下:

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

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

The compareAndSet method calls a native method to carry out the assignment. There are mainly two questions:

  1. 无限循环有什么帮助?
  2. 在什么情况下,如果 (compareAndSet(current,next))条件可能返回false? 在这种情况下,代码可能会陷入无限循环.如果是 保证compareAndSet将始终返回"true",然后可以 我们不会完全取消这张支票吗?
  1. How does the infinite loop help ?
  2. What could be the scenarios, under which the "if (compareAndSet(current, next))" condition could return a false ? In such a case, the code might run into an infinite loop. If it is guaranteed that compareAndSet will always return a "true", then can we not do away with this check altogether ?

decrementAndGetgetAndDecrementgetAndAdd方法也有类似的疑问.

Similar doubts are with the decrementAndGet, getAndDecrement, getAndAdd methods as well.

推荐答案

无限循环有什么帮助?

How does the infinite loop help ?

这意味着:重试直到起作用. 没有循环,第一次循环可能不会成功(见下文).

This means: retry until it worked. Without the loop, it may not succeed the first time around (see below).

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

What could be the scenarios, under which the "if (compareAndSet(current, next))" condition could return a false ?

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

That happens if two threads try to modify the value at the same time. One of them will get there first. The other one will fail.

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

Imagine two threads (A and B) trying to increment from 5 to 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

请注意,此类的全部要点是避免锁定.因此,您可以使用这种乐观的货币控制":只要假设没有其他人同时处理数据,并且如果发现错误,则回滚并重试.

Note that the whole point of this class is to avoid locks. So instead, you have this "optimistic currency control": Just assume no one else is working on the data at the same time, and if that turns out to be wrong, rollback and retry.

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

In such a case, the code might run into an infinite loop

并非如此.对于执行该值的其他所有线程,它只能失败一次.

Not really. It can only fail once for every other thread that does something to the value.

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

Thread A from above in the second iteration:

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

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

You could conceivably end up with one thread waiting forever if other threads incessantly update the value, but only then. To avoid that, you'd need some definition of "fairness" (which some other tools in the concurrency package support).

这篇关于AtomicInteger类中addAndGet的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆