在浏览ForkJoinPool的Java 8版本的代码时(我从Java 7中进行了一些有趣的更改),我遇到了这个构造(here):
do {} while (!blocker.isReleasable() &&
!blocker.block());
我正在努力解决为什么你会这样写,而不仅仅是
while (!blocker.isReleasable() &&
!blocker.block());
它只是一个语义/可读性选择,因为你可以将第一个结构读作do "nothing" while "conditions"
吗?或者我还缺少一些额外的好处吗?
答案 0 :(得分:54)
如果你阅读文件顶部的注释,就在类声明的下面,有一节解释了这个结构的用法:
Style notes
===========
[...]
There are several occurrences of the unusual "do {} while
(!cas...)" which is the simplest way to force an update of a
CAS'ed variable. There are also other coding oddities (including
several unnecessary-looking hoisted null checks) that help
some methods perform reasonably even when interpreted (not
compiled).
答案 1 :(得分:45)
ForkJoinPool
广泛使用来自compareAndSwap...
的{{1}},并且sun.misc.Unsafe
中do {} while (...)
的大部分事件都可以 - 正如其他答案所述 - 解释通过标题样式注释下的这个评论:
ForkJoinPool
选择使用写* There are several occurrences of the unusual "do {} while
* (!cas...)" which is the simplest way to force an update of a
* CAS'ed variable.
- 循环,空体为while
似乎是一个主要的风格选择。这在do {} while (condition)
中可能更清楚,它恰好在Java 8中更新。
在Java 7 HashMap
中,您可以找到:
HashMap
虽然围绕它的大部分代码也发生了变化,但很明显Java 8中的替换是这样的:
while (index < t.length && (next = t[index++]) == null)
;
第一个版本的缺点是,如果删除了单独的分号,它将根据以下行改变程序的含义。
如下所示,do {} while (index < t.length && (next = t[index++]) == null);
和while (...) {}
生成的字节码略有不同,但在运行时不会以任何方式影响任何内容。
Java代码:
do {} while (...);
生成的代码:
class WhileTest {
boolean condition;
void waitWhile() {
while(!condition);
}
void waitDoWhile() {
do {} while(!condition);
}
}
答案 2 :(得分:8)
除了任何潜在的性能优势外,还有明显的可读性优势。
使用while (X) ;
乍一看并不总是显而易见的分号,您可能会对以下语句或语句在循环内部感到困惑。例如:
while (x==process(y));
if (z=x) {
// do stuff.
}
很容易误解上面的内容,因为在循环中有if语句,即使你确实正确地读了它,也很容易认为这是编程错误而if应该在循环内部。
使用do {} while(X);
虽然可以立即一目了然地知道循环没有身体。
答案 3 :(得分:4)
如果您将阅读代码上方的评论,则会提到......
如果调用者不是ForkJoinTask
,则此方法在行为上等同于
while (!blocker.isReleasable())
if (blocker.block())
return;
}
所以这只是在else部分实现上述代码的另一种形式...... !!
在Style notes中提到了
有几次异常&#34; do {}同时发生 (!CAS ...)&#34;这是强制更新a的最简单方法 CAS&#39; ed变量。
如果你看到ManagedLocker#isReleasable的实现,它正在更新锁,如果不需要阻止,则返回true
。
解读:
空白while循环用于提供中断,直到某些条件重置为true / false。
此处,do { } while(!...)
是blocker.block()
true
blocker.isReleasable()
false
blocker
时阻塞/中断。!blocker.isReleasable()
循环将继续执行而blocker
不可释放(blocker.block()
)且do{ } while(...)
未被阻止! <{1}}设置为true后,执行将不再循环。
请注意,{{1}}不更新CAS变量,但它保证程序将等到变量更新(强制等待变量更新)。
答案 4 :(得分:0)
您可以使用以下方式轻松制作以下内容:
if(true){
//Do nothing ...
}