Страницы

Поиск по вопросам

четверг, 31 января 2019 г.

Java Memory Model и happens-before

Добрый день. Есть небольшой вопрос по 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 вполне может выполнить инструкции следующим образом:

Комментариев нет:

Отправить комментарий