【发布时间】:2013-05-02 12:15:38
【问题描述】:
while 与 do-while
while 和 do-while 在功能上是等效的当块为空时,虽然 while 看起来更自然:
do {} while (keepLooping());
while (keepLooping()) {}
带有空块的 while/do-while 的一个典型用例是使用 compareAndSet (CAS) 强制更新原子对象。例如,下面的代码将以线程安全的方式递增a:
int i;
AtomicInteger a = new AtomicInteger();
while (!a.compareAndSet(i = a.get(), i + 1)) {}
上下文
java.util.concurrent 的几个部分使用do {} while (...) 惯用语进行 CAS 操作,ForkJoinPool 的 javadoc 解释说:
不寻常的
do {} while (!cas...)多次出现,这是强制更新 CAS 变量的最简单方法。
既然他们承认这是不寻常的,我想他们的意思是最好的而不是最简单的。
问题
在某些情况下do {} while (!cas) 可以比while (!cas) {} 更高效,原因是什么?
【问题讨论】:
-
也许这只是历史偏好。无论如何,为什么要使用
{}---while (condition);是我要写的。 -
@MarkoTopolnik 同意
;。我找到了this video,Doug Lea 在 57:00 左右说:“不要使用 while,使用 do-while,因为安全点”,幻灯片提到“较小的比赛窗口”。我想他指的是 GC 安全点,尽管我看不出它在这里有何不同。 -
Doug 对此非常省略 :) 我可以解释它的最佳方式不是关于 do-while 与 while,而是关于使用循环体进行赋值与将所有内容都塞进条件中。
-
@MarkoTopolnik 这也是我所理解的——但是为什么会出现麻烦呢?我想 SO 不是最好的提问地点!
-
是的...这对 SO “没有建设性”,因为地球上只有大约三个人可以给出超出猜测的答案:)
标签: java performance while-loop do-while compare-and-swap