Что в действительности означает WAKEUP в контексте уведомлений / уведомлений? - PullRequest
1 голос
/ 30 июля 2010

некоторые комментарии здесь смутили меня! Я думал, что знаю это, и бог знает, что я написал тонну кода MT, но это было какое-то время ...

FWIK notify / notifyall

уведомление: один поток выбран из набора ожидания и перемещен в набор для получения блокировки монитора

notifyall: все темы "уведомлены" - они все перемещены в набор записей?

Значит ли это, что все они вновь получат замок, как только его освободит держатель замка? больше не нужно уведомлять?

- все ответы просто перефразируют то, что я читал в другом месте. Я понимаю, что только один из них может получить блокировку и т. Д., Мой вопрос такой: как только поток уведомляется, он начинает ждать на мониторе. право ? поэтому не нужно снова получать уведомление, если поток, удерживающий блокировку, вызывает notify

Ответы [ 3 ]

3 голосов
/ 30 июля 2010

Точное описание того, что происходит, см. В разделе JLS 17.8.2 .

Когда поток выполняет notifyAll для объекта блокировки, все остальные потоки, которые в данный момент ожидаютудаляются из окна ожидания блокировки;то есть они становятся управляемыми.Каждый из них затем пытается восстановить блокировку и, когда это удается, возвращается из вызова wait(...).

Конечно, потокам удается получить блокировку только по одному, и нет никаких гарантий справедливости.Но в конечном итоге все они получат замок.

1 голос
/ 30 июля 2010

Уведомление об ожидающих потоках происходит при вызове notifyAll. Все ожидающие потоки удаляются из набора ожидания объекта. Выбран только один поток из набора ожидания, для которого нет никакой гарантии относительно того, какой поток выбран

У langspec есть раздел на Уведомление о потоке

1 голос
/ 30 июля 2010

Когда вызывается notifyAll, все потоки, ожидающие этой блокировки, просыпаются, и один из них получает блокировку. Остальное возвращается в ожидание.

Может показаться, что notifyAll - это пустая трата ресурсов, но AFAIR были особые хитрые случаи, когда вызов notify может пробудить не тот поток, который не может справиться с ситуацией, что приводит к тупику. Поэтому было рекомендовано использовать notifyAll всегда.

Начиная с Java5, редко приходится беспокоиться о подобных вещах, потому что новые утилиты параллелизма почти всегда выполняют эти задачи лучше, чем wait и notify*, что делает их почти устаревшими. Типичное использование wait и notify* в блокировании очередей, и теперь у нас есть несколько готовых реализаций их - таких как LinkedBlockingQueue и PriorityBlockingQueue - доступных в библиотеке классов .

...