2014-10-05 70 views
0

有人可以解释为无穷大循环的目的....这是官方Java的AtomicBoolean getAndSet方法的定义什么在下面的代码

public final boolean getAndSet(boolean newValue) { 
     for (;;) { 
      boolean current = get(); 
      if (compareAndSet(current, newValue)) 
       return current; 
     } 
    } 

回答

2

在Java 8中,sourcecode已略有调整,使其更容易理解:

public final boolean getAndSet(boolean newValue) { 
    boolean prev; 
    do { 
     prev = get(); 
    } while (!compareAndSet(prev, newValue)); 
    return prev; 
} 

正如你所看到的,compareAndSet,它返回一个布尔值,它来自本地函数Unsafe.compareAndSwapInt,可能会失败。在这种情况下,操作只需重复一次。

Unsafe.compareAndSwapInt文件,

 
Atomically update Java variable to x if it is currently holding expected. 
Returns: 
    true if successful 

如果AtomicBoolean的价值一直呼吁get()Unsafe.compareAndSwapInt一些点之间变化的函数将失败。这通常不应该是这种情况,但是当它发生时,它会再次查询当前值,并希望同样的事情不会重复。

+0

谢谢你的回答。如果以某种方式c​​ompareAndSet不写入true和prev和newValue(因为它的计数器或其值不重复)将永远不会匹配。是否有使用for循环的特定原因?不应该有一些例外引发或其他退出策略? – 2014-10-08 12:28:28

+0

@ bharat9848:我不这么认为,因为compareAndSet可能失败的最常见情况是数据竞争,在这种情况下,它有可能在下一次迭代中工作。所以,为了简化调用方,最好不要抛出异常。即使它会抛出一个,你会怎么做?显示它?重试操作? – tilpner 2014-10-08 12:33:18

1

显然,这不是一个无限循环。环路只是有身体内部的退出条件:

return current; 

在一般情况下,这是乐观的,无锁的原子操作使用的典型成语。比较和交换(CAS)操作将重试直到它成功,并且一旦它不从另一个线程竞争,它就会成功。更确切地说,只要get()的返回值与compareAndSet()观察到的当前值相匹配,就会满足退出条件。很难而不是来满足这个条件,而且很少发生。

+0

感谢您的回答。如果以某种方式c​​ompareAndSet不写入true和prev和newValue(因为它的计数器或其值不重复)将永远不会匹配。是否有使用for循环的特定原因?不应该有一些例外引发或其他退出策略? – 2014-10-08 12:29:42

+0

不,重试正是所有无锁原子操作的预期策略。 – 2014-10-08 14:55:14

相关问题