Если ThreadB
проходит через свой блок synchronized
раньше, чем ThreadA
, то ThreadA
будет блокироваться на неопределенный срок при вызове wait
.Как-то не будет уведомлено, что другой поток уже завершен.
Проблема в том, что вы пытаетесь использовать wait
и notify
способами, которые не предназначены для использования.Обычно wait
и notify
используются для того, чтобы один поток ожидал выполнения некоторого условия, а затем чтобы другой поток сигнализировал о том, что условие могло стать истинным.Например, они часто используются следующим образом:
/* Producer */
synchronized (obj) {
/* Make resource available. */
obj.notify();
}
/* Consumer */
synchronized (obj) {
while (/* resource not available */)
obj.wait();
/* Consume the resource. */
}
Причина, по которой работает приведенный выше код, заключается в том, что не имеет значения, какой поток запускается первым.Если поток производителя создает ресурс, и никто не wait
использует obj
, то при запуске потребителя он входит в цикл while
, замечает, что ресурс создан, и затем пропускает вызов на * 1018.*.Затем он может потреблять ресурс.Если, с другой стороны, потребитель запускается первым, в цикле while
он заметит, что ресурс еще не доступен, и wait
уведомит некоторый другой объект.Затем можно запустить другой поток, создать ресурс и notify
потребительский поток, для которого доступен ресурс.Как только исходный поток будет пробужден, он заметит, что условие цикла больше не выполняется и будет потреблять ресурс.
В более общем случае Java предлагает всегда вызывать wait
в цикле из-за ложных уведомлений , в которых поток может проснуться от вызова на wait
, даже не будучи уведомленным ни о чем.Использование описанного выше шаблона может предотвратить это.
В вашем конкретном случае, если вы хотите убедиться, что ThreadB
завершил работу до выполнения ThreadA
, вы можете использовать Thread.join()
, который явно блокируетвызывающий поток, пока не выполнится какой-то другой поток.В более общем случае вы можете захотеть взглянуть на некоторые из других примитивов синхронизации, предоставляемых Java, поскольку их часто гораздо проще использовать, чем wait
и notify
.