Добрый день. Есть небольшой вопрос по JMM. Я знаю как работает happens-before, но не могу понять один момент. Вот код:
private static int x = 0;
private static volatile boolean flag = false;
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
x = 10;
while (!flag) ;
System.out.println(x);
}).start();
x = 5;
flag = true;
}
Какое значение должно принять X? Если какое-то правило чтобы определить это?
Ответ
Если изобразить потоки выполнения в вашем коде, мы получим такую картину:
Main thread - это основной поток вашей программы, Thread1 - поток, который вы явно создаете.
Запись и чтение волатильной переменной flag действительно создают отношение Happens-Before (E → B на диаграмме). Таким образом по отношению к вызову System.out.println(x); у нас есть два потока выполнения, для каждого из которых гарантируется порядок выполнения: A → B → C и D → E → B → C. Запись в переменную x произойдет гарантированно раньше ее чтения.
Но вот инструкции записи в переменную x (A и D) находятся в состоянии гонки (race condition) и их порядок выполнения друг относительно друга не определен. В итоге то, что мы видим на диаграмме никак нельзя назвать полным порядком. JVM вполне может выполнить инструкции следующим образом:
Комментариев нет:
Отправить комментарий