Хороший вопрос. Я думаю, что комментарии в реализации JDK7 Object проливают некоторый свет на это (выделено мной):
Этот метод заставляет текущий поток (назовите его T
) разместить
сам в ожидании, установленном для этого объекта , а затем отказаться от любого
и все заявки на синхронизацию для этого объекта .
...
Поток T
затем удаляется из набора ожидания для этого
обычным способом с другими потоками на право синхронизации на
объект; как только он получит контроль над объектом, все его
претензии синхронизации на объекте восстановлены в статус-кво
анте - то есть к ситуации на момент, когда wait
метод был вызван . Тема T
затем возвращается из
вызов метода wait
. Таким образом, по возвращении из
wait
метод, состояние синхронизации объекта и потока
T
точно так же, как это было, когда метод wait
был
прибег.
Поэтому я думаю, что первое, на что следует обратить внимание, это то, что wait()
не возвращается, пока вызывающий не закончит ожидание (очевидно). Это означает, что если бы сам wait()
был синхронизирован, то вызывающая сторона продолжала бы удерживать блокировку объекта, и никто другой не смог бы wait()
или notify()
.
Теперь, очевидно, wait()
делает что-то хитрое за кулисами, чтобы заставить вызывающего абонента в любом случае утратить право владения замком на объекте, но, возможно, этот трюк не сработает (или будет значительно сложнее выполнить работу), если wait()
Сам был синхронизирован.
Второй момент заключается в том, что если несколько объектов ожидают объекта, когда notify()
используется, чтобы разбудить ровно один из них, используется стандартный метод конкуренции, позволяющий синхронизировать только один поток на объекте, и что wait()
предполагается восстановить претензии вызывающей стороны на синхронизацию до точного состояния, в котором они находились до вызова wait()
. Мне кажется возможным, что требование, чтобы вызывающий абонент удерживал блокировку до вызова wait()
, упрощает это, поскольку устраняет необходимость проверять, должен ли вызывающий абонент продолжать удерживать блокировку после возврата wait()
. Контракт предусматривает, что вызывающая сторона должна продолжать удерживать блокировку, и, таким образом, некоторая часть реализации упрощается.
Или, возможно, это было просто сделано, чтобы избежать появления логического парадокса "если wait()
и notify()
синхронизированы, и wait()
не возвращается до тех пор, пока не будет вызван notify()
, как это возможно?" успешно использоваться? "
В любом случае, это мои мысли.