Почему wait() и notify () объявлены в классе объектов Java?


Почему wait() и notify() методы, объявленные в Object класса, а не Thread класса?

9 52

9 ответов:

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

Я думаю, что вы ошибаетесь о том, как эти методы работают. Они не просто на уровне детализации потока, т. е. это не случай просто вызова wait() и быть разбуженным следующим звонком в notify(). Скорее, вы всегда звоните wait() на определенном объекте, и будет разбужен только вызовами notifyна что объект.

это хорошо, потому что в противном случае примитивы параллелизма просто не будут масштабироваться; это было бы эквивалентно наличию глобальных пространств имен, так как любые вызовы notify() в любом месте вашей программы будет иметь потенциал, чтобы испортить любой параллельный код, как они будут просыпаться любые потоки блокировки на wait() звонок. Следовательно, причина, по которой вы вызываете их на определенный объект; это дает контекст для пары wait-notify для работы, поэтому при вызове myBlockingObject.notify(), на частном объекте вы можете быть уверены, что вы только разбудите потоки, которые вызвали методы wait в вашем классе. Некоторые пружинные нити, которые могут ожидать другого объекта, не будут разбужены этим вызовом, и наоборот.

Edit: или обратиться к нему с другой точки зрения - я ожидаю от вашего вопроса Вы думали, что получите дескриптор к ожидающему потоку и вызовите notify() on что нить чтобы разбудить его. Почему это не сделано таким образом, что вы бы приходится много заниматься домашним хозяйством самостоятельно. Поток, который будет ждать, должен будет опубликовать ссылку на себя где-то, чтобы другие потоки могли ее видеть; это должно быть правильно синхронизировано для обеспечения согласованности и видимости. И когда вы хотите разбудить нить, вам нужно будет получить эту ссылку, разбудить ее и удалить ее из того места, где вы ее читаете. Там гораздо больше ручных лесов участвует, и гораздо больше шансов пойти не так с ним (особенно в параллельном режиме окружающая среда) по сравнению с просто вызовом myObj.wait() в спящем потоке, а затем myObj.notify() в потоке waker.

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

потому что только один поток одновременно может владеть монитором объекта, и этот монитор-это то, что потоки ждут или уведомляют. Если Вы читаете документация на Object.notify() и Object.wait() это подробно описано.

механизм синхронизации включает в себя понятие - мониторинг объекта. Когда вызывается wait (), монитор запрашивается и дальнейшее выполнение приостанавливается до тех пор, пока монитор не будет получен или не произойдет исключение InterruptedException. При вызове функции notify() монитор освобождается.

возьмем сценарий, если wait() и notify() были помещены в класс Thread вместо класса Object. В какой-то момент кода, currentThread.wait() вызывается, а затем объект anObject is доступный.

//.........
currentThread.wait();
anObject.setValue(1);
//.........

когда currentThread.wait() называется, монитор currentThread запрашивается, и дальнейшее выполнение не выполняется до тех пор, пока не будет получен монитор или не произойдет исключение InterruptedException. Теперь, находясь в состоянии ожидания, если метод foo() другого объекта anotherObject проживающего в currentThread вызывается из другого потока, он застрял, хотя назвать метод foo() не работает anObject. Если первый метод wait () был вызван на anObject, вместо самого потока, другие вызовы методов (не доступ anObject) на объектах, находящихся в одном потоке, не застрянет.

таким образом, вызов методов wait() и notify() в классе объектов(или его подклассах) обеспечивает больший параллелизм, и поэтому эти методы находятся в классе объектов, а не в классе потоков.

в некоторых других ответах используется слово "монитор", но никто не объясняет, что это значит.

имя "монитор" было придумано еще в 1970-х годах, и оно относилось к объекту, который имел свой собственный внутренний замок и связанный с ним механизм ожидания/уведомления. https://en.wikipedia.org/wiki/Monitor_%28synchronization%29

двадцать лет спустя, был короткий момент времени, когда настольные, многопроцессорные компьютеры были новыми, и было модно думать, что правильным способом разработки программного обеспечения для них было бы создание объектно-ориентированных программ, в которых объект был монитор.

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

читать здесь для объяснения wait и Notify.

было бы лучше, чтобы избежать их, однако, в ваших приложениях и использовать новые java.утиль.одновременно пакета.

Я скажу это простым способом:

для вызова wait() или notify() вам нужно владеть монитором объекта - это означает, что wait() или notify () должны присутствовать в синхронизированном блоке

synchronized(monitorObj){
monitorObj.wait()  or even notify
}

вот почему эти методы присутствуют в объект класса

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

методы ожидания и уведомления используются связь между двумя потоками в Java. Таким образом, класс объектов является правильным местом, чтобы сделать их доступными для каждого объекта в Java.

еще одна причина заключается в том, что блокировки доступны для каждого объекта. Потоки нуждаются в блокировке, и они ждут блокировки, они не знают, какие потоки держат блокировку, вместо этого они просто знают, что блокировка удерживается каким-то потоком, и они должны ждать блокировки вместо того, чтобы знать, какой поток находится внутри синхронизированного блока и спрашивать их чтобы освободить замок