"条件"时"无所事事"

Eri*_*aas 69 java while-loop do-while

在浏览JavaJ版本的ForkJoinPool的代码时(我从Java 7中进行了一些有趣的更改),我遇到了这个构造(这里):

do {} while (!blocker.isReleasable() &&
             !blocker.block());
Run Code Online (Sandbox Code Playgroud)

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

while (!blocker.isReleasable() &&
       !blocker.block());
Run Code Online (Sandbox Code Playgroud)

它只是一个语义/可读性选择,因为你可以读取第一个结构do "nothing" while "conditions"吗?或者我还缺少一些额外的好处?

Mic*_*Sim 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).
Run Code Online (Sandbox Code Playgroud)

  • 由于我自己需要提醒:CAS是http://en.wikipedia.org/wiki/Compare-and-swap (25认同)
  • 您可能已经解释了构造如何帮助"强制更新CAS变量". (14认同)
  • 但是为什么它会导致更新CAS变量而不像`while`版本? (7认同)
  • 它没有说明{while}(条件)与while(条件)是否相同; 有所作为.如果它有所不同,那么这是(a)一个糟糕的坏评论,(b)我认为它是_bug_没有在声明本身发表评论,而且(c)它有所作为的事实是一个主要的WTF in语言. (4认同)
  • 这听起来像是深刻的魔法,其中范围改变`do {} while()`避免了`while()`使用的JIT优化.while语句在语义上是等效的,因此差异必须在JVM的实现中. (3认同)

Eri*_*aas 45

ForkJoinPool大量使用compareAndSwap...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. 
Run Code Online (Sandbox Code Playgroud)

选择使用写一个while空体的a -loop do {} while (condition)似乎是一个主要的风格选择.这可能更清楚HashMap,恰好在Java 8中更新.

在Java 7中,HashMap您可以找到:

while (index < t.length && (next = t[index++]) == null)
    ;
Run Code Online (Sandbox Code Playgroud)

虽然围绕它的大部分代码也发生了变化,但很明显Java 8中的替换是这样的:

do {} while (index < t.length && (next = t[index++]) == null);
Run Code Online (Sandbox Code Playgroud)

第一个版本的缺点是,如果单独的分号被删除,它将根据以下行改变程序的含义.

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

Java代码:

class WhileTest {
    boolean condition;

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

    void waitDoWhile() {
        do {} while(!condition);
    }
}
Run Code Online (Sandbox Code Playgroud)

生成的代码:

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        
}
Run Code Online (Sandbox Code Playgroud)

  • 来自[重复的问题](http://stackoverflow.com/questions/37323549/weird-loops-used-in-spliterator-of-java-8):这个恕我直言,是一个比它更好,更有说服力的答案目前接受一个. (2认同)

Tim*_*m B 8

撇开任何潜在的性能优势,都有明显的可读性优势.

对于while (X) ;尾随分号乍一看并不总是显而易见的,您可能会对以下语句或语句在循环内部感到困惑.例如:

while (x==process(y));
if (z=x) {
    // do stuff.
}
Run Code Online (Sandbox Code Playgroud)

很容易误解上面的内容,因为在循环中有if语句,即使你确实正确地读了它,也很容易认为这是编程错误而if应该在循环中.

随着do {} while(X);虽然它立即一目了然,没有身体的循环.