在“条件”的同时“什么都不做”

2022-08-31 14:10:45

在浏览Java 8版本的ForkJoinPool(与Java 7相比有一些有趣的变化)的代码时,我遇到了这个结构(这里):

do {} while (!blocker.isReleasable() &&
             !blocker.block());

我正在努力为什么你会这样写,而不仅仅是

while (!blocker.isReleasable() &&
       !blocker.block());

它是否只是一个语义/可读性选择,因为您可以将第一个构造解读为?还是我错过了一些额外的好处?do "nothing" while "conditions"


答案 1

如果您阅读文件顶部的注释,就在类声明的正下方,有一节解释了此构造的用法:

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).

答案 2

ForkJoinPool广泛使用 from 和 大多数 in 的出现都可以 - 正如其他答案所提到的 - 通过标题样式注释下的此注释来解释:compareAndSwap...sun.misc.Unsafedo {} 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. 

然而,选择使用带有空体的 -循环似乎是一种主要的风格选择。这在 中可能更清楚,它恰好在 Java 8 中更新了。whiledo {} while (condition)HashMap

在Java 7中,你可以找到这个:HashMap

while (index < t.length && (next = t[index++]) == null)
    ;

虽然围绕它的许多代码也发生了变化,但很明显,Java 8中的替代品是这样的:

do {} while (index < t.length && (next = t[index++]) == null);

第一个版本有一个弱点,即如果孤独的分号碰巧被删除,它将根据以下行更改程序的含义。

如下图所示,由 和 生成的字节码略有不同,但不会以任何方式影响运行时的任何内容。while (...) {}do {} while (...);

Java 代码:

class WhileTest {
    boolean condition;

    void waitWhile() {
        while(!condition);
    }

    void waitDoWhile() {
        do {} while(!condition);
    }
}

生成的代码:

class WhileTest {
  boolean condition;

  WhileTest();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  void waitWhile();
    Code:
       0: aload_0       
       1: getfield      #2                  // Field condition:Z
       4: ifne          10
       7: goto          0
      10: return        

  void waitDoWhile();
    Code:
       0: aload_0       
       1: getfield      #2                  // Field condition:Z
       4: ifeq          0
       7: return        
}

推荐