San*_*ich 4 java synchronization atomic java-6
我正在为类中的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;
}
}
Run Code Online (Sandbox Code Playgroud)
compareAndSet方法调用本机方法来执行赋值.主要有两个问题:
类似的质疑是与decrementAndGet,getAndDecrement,getAndAdd方法为好.
Thi*_*ilo 10
无限循环如何帮助?
这意味着:重试直到它工作.没有循环,第一次可能不会成功(见下文).
可能是什么情况,"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
Run Code Online (Sandbox Code Playgroud)
请注意,此类的重点是避免锁定.所以相反,你有这种"乐观的货币控制":假设没有其他人同时处理数据,如果结果是错误的,则回滚并重试.
在这种情况下,代码可能会遇到无限循环
并不是的.对于对该值起作用的每个其他线程,它只能失败一次.
第二次迭代中从上面开始的线程A:
A: int current = get(); => current now 6
A: int next = current + delta; => next = 7
A: if (compareAndSet(current, next)) => now OK
Run Code Online (Sandbox Code Playgroud)
如果其他线程不断更新值,那么你可以想象最终会有一个线程永远等待,但只有这样.为了避免这种情况,你需要一些"公平"的定义(并发包中的一些其他工具支持).