为什么这个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。