java: wait (), notify () и синхронизированные блоки - PullRequest
8 голосов
/ 07 июля 2010

Я узнал, что вызов метода wait() объекта освободит монитор объекта, если он присутствует.

Но у меня есть несколько вопросов относительно вызова notify() для этого объекта другим потоком:

  1. (когда) активируется ожидающий поток, если другой (3-й) поток в это время владеет монитором объекта?

  2. активируется ли ожидающий поток, если 3-й поток с именем wait() для этого объекта?

  3. можно ли определить, ожидает ли поток уведомления об определенном объекте (java 1.4 / java 5)

  4. Что будет, если wait() будет вызван в методе finalize()?

Ответы [ 4 ]

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

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

Когда вы вызываете notify (), поток готов к запуску, но это не значит, что он будет выполнен немедленно, поэтому будьте осторожны.

  1. Это приведет к пробуждению потокаиз набора ожидания случайным образом.

  2. Вы не знаете, кто из них проснется первым, он не следует ни за каким порядком.

  3. Thread.getState ()

  4. Вы бы создали тупик.

2 голосов
/ 07 июля 2010
  1. notify разбудит одну нить, ожидающую на мониторе.До тех пор, пока монитор не будет закрыт, ни один поток не может быть запущен;Функция wait () должна вызываться в синхронизированном блоке, поэтому для продолжения работы этого блока необходимо удерживать блокировку.
  2. Нет гарантий.Звоните notifyAll, чтобы дать всем нитям шанс проснуться.
  3. Не знаю.Вы могли бы задать потоку переменную, говорящую, что он ждет, прежде чем переходит в спящий режим ...
  4. Это, вероятно, плохая идея.Можете ли вы придумать ситуацию, когда это необходимо?
2 голосов
/ 07 июля 2010
  1. Вот почему у вас есть методы notify() и notifyAll(). Первый пробуждает один поток, ожидающий объекта, второй пробуждает все потоки. Ожидающий поток не проснется, если в другом потоке вызывается wait().

  2. номер

  3. Можно только вызвать thread.holdsLock(obj), чтобы узнать, удерживает ли поток блокировку монитора для определенного объекта.

  4. Не вызывайте wait() в методе финализации.

0 голосов
/ 07 июля 2010

2: не обязательно.notify() пробуждает один ожидающих потоков.Это может быть оригинал или третий.

3: Используя thread.getState(), вы можете узнать, ожидает ли поток объект, но я не знаю, всегда ли вы можете узнать, какой объектэто точно.

...