Тема застряла заняты ожидания в некоторых обстоятельствах, а не в других

У меня довольно странная проблема с занятым ожиданием потока Java.

У меня есть один поток, который занят ожидает состояния статической переменной какого-то другого потока. Допустим, поток, который занят занят, ожидает, что статическая переменная int другого потока достигнет определенного значения.

while(OtherThread.countInt < 5);

Если я воспользуюсь приведенным выше кодом, поток застрянет в состоянии ожидания и не выйдет из цикла while, даже если static int countInt действительно достигает 5.

while(OtherThread.countInt < 5) {
    // waste some time doing meaningless work
}

Однако, если я использую этот другой код, то поток действительно выходит из цикла занятости. Иногда, как только countInt достигает 5, в другое время немного позже. Но так бывает. Для моего конкретного примера я использовал это как "бессмысленную работу"

print("busy waiting...",1000) // wasting time doing meaningless work

где я определил print как synchronzied static void print(String s, int n) который печатает строку s а потом спит n миллисекунды.

Что дает? Почему поток застревает в ожидании первого кода, а не другого? Все потоки имеют одинаковые приоритеты, поэтому проблема не может быть приоритетной.

1 ответ

countInt не volatileследовательно, изменение не гарантируется, чтобы быть видимым ожидающему потоку.

Так как ваш print() метод synchronized вероятно, он создает достаточный барьер памяти, чтобы обновленное значение стало видимым для вашего while петля. Это по сути совпадение; while Само условное все еще нарушено. Вот почему так важно правильно спроектировать и протестировать параллельный код - легко написать что-то, что работает только так , как задумано, но позже не получится (например, под нагрузкой, на другом процессоре, после, казалось бы, безопасного рефакторинга и т. Д.),

Используйте надлежащий барьер памяти, такой как synchronised читать и писать volatile поле, или механизм связи между потоками, такие как в java.util.concurrent, Есть ряд связанных с этим вопросов volatile и эти другие инструменты.

Вы также хорошо бы изучили поддержку параллелизма в Java. Межпотоковое общение нетривиально.

Другие вопросы по тегам