Чувствительная операция в моей лаборатории сегодня прошла совершенно неправильно. Привод на электронном микроскопе прошел через его границу, и после цепочки событий я потерял 12 миллионов долларов оборудования. Я сузил более 40 тыс. Строк в неисправном модуле:
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, я думаю, что с этим кодом ничего плохого. Однако, несмотря на вывод, указывающий, что программа не достигла условия выхода, она достигла условия выхода (достигнута ли она как и?). Почему?
Я заметил, что это не происходит в некоторых средах. Я нахожусь на OpenJDK 6 на 64-разрядной Linux.