为什么这个Java程序会终止,尽管显然它不应该(也没有)?
今天,我实验室的一项敏感手术完全出错了。电子显微镜上的一个执行器越过了它的边界,在一系列事件之后,我损失了1200万美元的设备。我已经将故障模块中的40K行缩小到以下范围:
import java.util.*;
class A {
static Point currentPos = new Point(1,2);
static class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(String[] args) {
new Thread() {
void f(Point p) {
synchronized(this) {}
if (p.x+1 != p.y) {
System.out.println(p.x+" "+p.y);
System.exit(1);
}
}
@Override
public void run() {
while (currentPos == null);
while (true)
f(currentPos);
}
}.start();
while (true)
currentPos = new Point(currentPos.x+1, currentPos.y+1);
}
}
我得到的输出的一些示例:
$ java A
145281 145282
$ java A
141373 141374
$ java A
49251 49252
$ java A
47007 47008
$ java A
47427 47428
$ java A
154800 154801
$ java A
34822 34823
$ java A
127271 127272
$ java A
63650 63651
由于这里没有任何浮点算术,并且我们都知道Java中的有符号整数在溢出时表现良好,因此我认为此代码没有问题。但是,尽管输出指示程序未达到退出条件,但它达到了退出条件(既达到又未达到?)。为什么?
我注意到这在某些环境中不会发生。我在64位Linux上使用OpenJDK 6。