В JSR-133 раздел 3.1 , в котором обсуждается видимость действий между потоками - упоминается, что приведенный ниже пример кода, в котором не используется ключевое слово volatile для логического поля, может стать бесконечным Цикл, если два потока работают. Вот код из JSR:
class LoopMayNeverEnd {
boolean done = false;
void work() {
while (!done) {
// do work
}
}
void stopWork() {
done = true;
}
}
Вот цитата важного бита в этом разделе, который меня интересует:
... Теперь представьте, что созданы два потока, и этот
поток вызывает work (), а в какой-то момент другой поток вызывает stopWork (). Потому что
отношения между двумя потоками не происходит - поток в цикле может никогда
увидеть обновление, выполненное другим потоком ...
А вот мой собственный Java-код, который я написал, чтобы увидеть цикл:
public class VolatileTest {
private boolean done = false;
public static void main(String[] args) {
VolatileTest volatileTest = new VolatileTest();
volatileTest.runTest();
}
private void runTest() {
Thread t1 = new Thread(() -> work());
Thread t2 = new Thread(() -> stopWork());
t1.start();
t2.start();
}
private void stopWork() {
done = true;
System.out.println("stopped work");
}
private void work() {
while(!done){
System.out.println("started work");
}
}
}
Хотя результаты последовательных казней отличаются - как и ожидалось - я не вижу, чтобы это когда-либо попадало в бесконечный цикл. Я пытаюсь понять, как я могу смоделировать бесконечный цикл, который предлагает документация, что мне не хватает? Как при объявлении логического volatile удалить бесконечный цикл?