示例代码:
public class Unbelievable {
public void test() {
int a = 5;
while ((a -= 2) > 0){
//代码
}
System.out.println("result= " + a);
}
public static void main(String[] args) {
Unbelievable un = new Unbelievable();
for (int i = 0; i < 2000_0; i++) {
un.test();
}
}
}
输出结果:
result= -1
result= -1
result= -1
result= -1
…
result= /
result= /
result= /
result= /
result= /
result= /
result= /
result= /
result= /
其中12821个输出 result= -1 ,7179个输出 result= /
1、问题原因
这是一个已知的bug。这里有两个关于它的bug的说明文档:
JDK-8231988 : Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop
JDK-8235327 : the "while" loop output wrong integer
这个bug应该在以下版本中修复:
JDK 11: > 11.0.6
JDK 8: > 8u251
OpenJDK: > openjdk8u242
2、解决方法
在不更新JDK的版本的情况下,可以只需禁用jit或使用AtomInteger来解决。例如,
public class WhileLoopTest {
public void test2() {
AtomicInteger i = new AtomicInteger(8);
while ((i.addAndGet(-3)) > 0) ;
System.out.println("i = " + i.intValue());
}
public static void main(String[] args) {
WhileLoopTest tst = new WhileLoopTest();
for (int i = 0; i < 50_000; i++) {
tst.test2();
}
}
}