Рассмотрим следующий код:
public class Example {
@SneakyThrows
private static VarHandle init() {
MethodHandles.Lookup lookup = MethodHandles.lookup();
return lookup.findStaticVarHandle(Example.class, "x", int.class);
}
private final static VarHandle X = init();
private static int x;
public static void main(String[] args) throws Exception {
Thread thread = new Thread(() -> {
System.out.println("Gonna wait till x becomes 1");
while ((int) X.get() != 1) ;
System.out.println("x is now 1");
});
thread.start();
new Thread(() -> {
// System.out.println("Sleeping for 1 second");
// sleep(1000); // uncomment this statement to reproduce
X.set(1);
}).start();
thread.join();
}
@SneakyThrows
public static void sleep(long ms) {
Thread.sleep(ms);
}
}
Когда я раскомментирую оператор sleep(1000);
и перекомпилирую его обратно для запуска, программа зацикливается навсегда. Теперь, чтобы решить эту проблему, я могу использовать Thread.onSpinWait();
после while((int) X.get() != 1)
, но мне действительно интересно понять, почему программа делает это в первую очередь?
Примечание: @SneakyThrows
от lombok и там, чтобы код было легко читать. Это похоже на обычный блок try-catch.