Почему потоки спонтанно просыпаются от wait ()? - PullRequest
19 голосов
/ 30 марта 2010

Мне было интересно, почему потоки спонтанно просыпаются от wait () в Java.
Это дизайнерское решение? Это компромисс?

РЕДАКТИРОВАТЬ: (из Java параллелизма на практике, стр. 300)

wait разрешено даже возвращать «ложно» - ни в коем случае не в ответ вызывающий поток уведомить.

Далее авторы утверждают:

это как тостер с рыхлым соединение, которое делает звонок когда тост готов, но и иногда, когда он не готов.

Вот почему вы всегда должны кодировать как

synchronized(this){
    while(!condition)
        wait();
    }
}

и никогда

synchronized(this){
    if(!condition){
        wait();
    }
}

Даже если условие переходит только из false до true.

Ответы [ 2 ]

24 голосов
/ 30 марта 2010

Эти спонтанные пробуждения также называют «ложными пробуждениями». В спецификации Java ложные пробуждения разрешены (хотя и не приветствуются) для реализаций jvm.

Причина, по которой они разрешены, заключается в том, что многие реализации могут быть основаны на pthreads (потоках POSIX), которые имеют такое поведение. Почему?

Википедия:

По словам Дэвида Р. Бутенхофа Программирование с помощью потоков POSIX ISBN 0-201-63392-2: «Это означает, что когда вы ждете переменную условия, ждать может (иногда) вернуться, когда нет нить конкретно вещать или сигнализировал эту переменную условия. Ложные пробуждения могут звучать странно, но в некоторых многопроцессорных системах сделать условие пробуждения полностью предсказуемый может существенно замедлить все операции с переменными условиями. условия гонки, которые вызывают ложные пробуждения следует считать редкими. "

10 голосов
/ 30 марта 2010

Сложно ответить на это однозначно, поскольку в спецификации языка Java не указано , почему реализация JVM может захотеть сделать это (в этом разделе указано только, что она может ), но я нашел довольно интересную историю ложных пробуждений в Википедии .

Фактическая статья о потоках POSIX, но я не думаю, что это слишком далеко, чтобы предполагатьна то, что на потоки в Java оказало определенное влияние поведение потоков POSIX:

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

Эта цитата принадлежит Дэвиду Р. Бутенхофу, который затем говорит:

Хотя действительно былинекоторые члены рабочей группы, которые утверждали, что теоретически можно представить, что может быть такая реализация, на самом деле причина не в этом.(И они так и не смогли доказать это.) Потоки POSIX были результатом большой напряженности между прагматичными программистами в реальном времени и в основном академическими исследователями.Ложные пробуждения - это механизм академической клики компьютерных ученых, позволяющий каждому писать чистый код, проверяющий и проверяющий предикаты!

"Но (возможно) в значительной степени ложный (или, по крайней мере, загадочно-философский) аргумент" эффективности "прошел лучше с людьми в реальном времени, и реальная причина обычно отводилась на второе место в обосновании.

"Я много раз думал о том, как вы могли бы построить правильную и практическую реализацию, которая действительно имела бы ложные пробуждения.Мне никогда не удавалось построить пример.Однако это не значит, что его нет, и это хорошая история.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...