java在“条件”时“不做任何事情”
在浏览ForkJoinPool的Java 8版本(与Java 7相比有一些有趣的变化)的代码时,我遇到了这个构造(here):
do {} while (!blocker.isReleasable() &&
!blocker.block());
我在琢磨你为什么要这样写,而不是仅仅
while (!blocker.isReleasable() &&
!blocker.block());
这仅仅是语义/可读性的选择,因为您可以将第一个构造读取为do "nothing" while "conditions"
?还是我还缺少一些额外的好处
# 1 楼答案
撇开任何潜在的性能优势不谈,还有一个明显的可读性优势
使用
while (X) ;
后接分号乍一看并不总是明显的,您可能会误以为以下语句在循环中。例如:很容易将上面的内容误读为在循环中包含if语句,即使您正确地阅读了它,也很容易认为这是编程错误,if应该在循环中
使用
do {} while(X);
尽管一眼就能看出循环中没有主体# 2 楼答案
如果您阅读代码上面的注释,就会发现
如果调用方不是
ForkJoinTask
,则此方法在行为上等同于所以这只是在其他部分实现上述代码的另一种形式
在{a1}中提到
如果您将看到ManagedLocker#isReleasable的实现,它将更新锁,如果不需要阻塞,则返回
true
解释:
空白while循环用于提供中断,直到某些条件重置为真/假
这里,
do { } while(!...)
是一个阻断器/中断,直到blocker.block()
将true
当blocker.isReleasable()
为false
时。循环将在blocker
不可发布(!blocker.isReleasable()
)且blocker
未被阻止时继续执行!!一旦blocker.block()
设置为true,执行将脱离循环注意,
do{ } while(...)
不更新CAS变量,但它保证程序将等待变量更新(强制等待变量更新)# 3 楼答案
您可以使用以下工具轻松制作类似的内容:
# 4 楼答案
如果您阅读了文件顶部的注释,就在类声明的下方,则会有一节解释此构造的用法:
# 5 楼答案
ForkJoinPool
广泛使用了来自sun.misc.Unsafe
的compareAndSwap...
,并且do {} while (...)
在ForkJoinPool
中出现的大多数do {} while (...)
可以通过标题下的注释解释,正如其他答案所述:然而,选择使用空主体为}中可能更清楚,它碰巧在Java8中更新了
do {} while (condition)
的while
-循环似乎是一种风格上的选择。这在{在Java 7
HashMap
中,您可以找到以下内容:虽然它周围的许多代码也发生了变化,但很明显,Java 8中的替代品是:
第一个版本的缺点是,如果碰巧删除了单独的分号,它将根据下面的行更改程序的含义
如下所示,由
while (...) {}
和do {} while (...);
生成的字节码略有不同,但在运行时不会产生任何影响Java代码:
生成的代码: