今天我实验室的一个敏感手术完全出了差错。一个电子显微镜上的驱动器超出了它的边界,在一系列事件之后,我损失了价值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中溢出时表现良好,所以我认为这段代码没有任何问题。然而,尽管输出表明程序没有达到退出条件,但它达到了退出条件(它都达到了而且 not reached?)为什么?
我注意到这在某些环境中不会发生。我在64位Linux上的OpenJDK 6上。