有人可以解释为无穷大循环的目的....这是官方Java的AtomicBoolean getAndSet方法的定义什么在下面的代码
public final boolean getAndSet(boolean newValue) {
for (;;) {
boolean current = get();
if (compareAndSet(current, newValue))
return current;
}
}
有人可以解释为无穷大循环的目的....这是官方Java的AtomicBoolean getAndSet方法的定义什么在下面的代码
public final boolean getAndSet(boolean newValue) {
for (;;) {
boolean current = get();
if (compareAndSet(current, newValue))
return current;
}
}
在Java 8中,sourcecode已略有调整,使其更容易理解:
public final boolean getAndSet(boolean newValue) {
boolean prev;
do {
prev = get();
} while (!compareAndSet(prev, newValue));
return prev;
}
正如你所看到的,compareAndSet,它返回一个布尔值,它来自本地函数Unsafe.compareAndSwapInt,可能会失败。在这种情况下,操作只需重复一次。
Atomically update Java variable to x if it is currently holding expected. Returns: true if successful
如果AtomicBoolean
的价值一直呼吁get()
和Unsafe.compareAndSwapInt一些点之间变化的函数将失败。这通常不应该是这种情况,但是当它发生时,它会再次查询当前值,并希望同样的事情不会重复。
显然,这不是一个无限循环。环路只是有身体内部的退出条件:
return current;
在一般情况下,这是乐观的,无锁的原子操作使用的典型成语。比较和交换(CAS)操作将重试直到它成功,并且一旦它不从另一个线程竞争,它就会成功。更确切地说,只要get()
的返回值与compareAndSet()
观察到的当前值相匹配,就会满足退出条件。很难而不是来满足这个条件,而且很少发生。
感谢您的回答。如果以某种方式compareAndSet不写入true和prev和newValue(因为它的计数器或其值不重复)将永远不会匹配。是否有使用for循环的特定原因?不应该有一些例外引发或其他退出策略? – 2014-10-08 12:29:42
不,重试正是所有无锁原子操作的预期策略。 – 2014-10-08 14:55:14
谢谢你的回答。如果以某种方式compareAndSet不写入true和prev和newValue(因为它的计数器或其值不重复)将永远不会匹配。是否有使用for循环的特定原因?不应该有一些例外引发或其他退出策略? – 2014-10-08 12:28:28
@ bharat9848:我不这么认为,因为compareAndSet可能失败的最常见情况是数据竞争,在这种情况下,它有可能在下一次迭代中工作。所以,为了简化调用方,最好不要抛出异常。即使它会抛出一个,你会怎么做?显示它?重试操作? – tilpner 2014-10-08 12:33:18