java: wait (), notify () и синхронизированные блоки

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

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

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

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

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

  4. что происходит, если wait() будет вызван в finalize() способ?

4 ответов


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

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

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

  1. Он проснулся бы какой-нить из waitset случайным образом.

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

  3. нить.getState()

  4. вы создадите тупик.


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

  2. нет.

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

  4. Не называй wait() в аськи метод.


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

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