while vs. do-while
while和do-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) {}
且出于何种原因的情况?
答案 0 :(得分:2)
所以'做什么'意味着它将在while循环中运行一次代码。然后,如果条件为真,它只在while循环内运行代码。
简单演示
boolean condition = false;
do{
System.out.Println("this text displayed");
}while(condition == true);
输出"显示此文字"
正常
while(condition == true){
System.out.Println("this text displayed");
}
输出""
为什么或在哪里使用,我没有满足需要,所以我无法帮助你。这只是一个确定问题/需求的问题,并使用您所知道的解决问题。类似于乐高 - 机械类不是'阻止'
答案 1 :(得分:0)
可能存在这样的情况:期望和更新的计算是复杂的,可以在调用compareAndSet的同一行中读取。 然后你可以在do:
中使它更具可读性do {
int expect = a.get();
int update = expect + 1;
} while (!a.compareAndSet(expect, update));
答案 2 :(得分:0)
这不是效率问题。如果没有do {} while(),有些情况就无法解决。看一下java.util.Random.next(int bits)。如果你尝试对while(){}执行相同的操作,那么你会有一个代码重复,因为循环体必须在条件之前执行一次。
我已经问了一个非常类似的问题:compiling loops in Java。
此代码:
public class Test {
static int i = 0;
public static void main(String[] args) {
method1();
method2();
}
public static void method2() {
do{}while(++i < 5);
}
public static void method1() {
while(++i < 5);
}
}
编译成:
public static void method2();
Code:
0: getstatic #4; //Field i:I
3: iconst_1
4: iadd
5: dup
6: putstatic #4; //Field i:I
9: iconst_5
10: if_icmplt 0
13: return
public static void method1();
Code:
0: getstatic #4; //Field i:I
3: iconst_1
4: iadd
5: dup
6: putstatic #4; //Field i:I
9: iconst_5
10: if_icmpge 16
13: goto 0
16: return
您可能会注意到method1()中第13行的其他说明。但正如我在问题中的答案所建议的那样,当JIT编译成机器指令时,这没有任何区别。非常难以捉摸的性能提升。任何证明它的方法你必须使用PrintAssembly键运行。理论上,方法2更快,但在实践中它们应该是平等的。