Почему ожидание () и уведомляет () объявленный в Классе объекта Java?

JVM очень широко распространена, особенно в корпоративном мире, по крайней мере, где я работал, всегда была установленная JVM.

я в настоящее время работаю над Апплетом Java, но в целом, я никогда не был бы апплет, если я не имел к. Но с другой стороны, я не использовал бы Flash или Silverlight, также. Апплеты имеют медленное время загрузки и выглядят неуместными на веб-страницах. Кроме того, Macromedia/Adobe имеют outmarketed старые добрые апплеты.

53
задан Pops 4 May 2011 в 08:09
поделиться

5 ответов

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

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

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

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

Ожидающий поток должен опубликовать ссылку на себя где-нибудь, чтобы другие потоки могли ее увидеть; это должно быть должным образом синхронизировано для обеспечения согласованности и видимости. И когда вы хотите разбудить поток, вам нужно будет получить эту ссылку, разбудить ее и удалить откуда бы вы ее ни читали. Здесь задействовано гораздо больше ручных скаффолдингов и гораздо больше шансов ошибиться (особенно в параллельной среде) по сравнению с простым вызовом myObj.wait () в спящем потоке, а затем myObj .notify () в потоке Waker.

Ожидающий поток должен опубликовать ссылку на себя где-нибудь, чтобы другие потоки могли ее увидеть; это должно быть должным образом синхронизировано для обеспечения согласованности и видимости. И когда вы хотите разбудить поток, вам нужно будет получить эту ссылку, разбудить ее и удалить откуда бы вы ее ни читали. Здесь задействовано гораздо больше ручных скаффолдингов и намного больше шансов ошибиться (особенно в параллельной среде) по сравнению с простым вызовом myObj.wait () в спящем потоке, а затем myObj .notify () в потоке Waker.

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

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

42
ответ дан 7 November 2019 в 08:50
поделиться

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

10
ответ дан 7 November 2019 в 08:50
поделиться

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

8
ответ дан 7 November 2019 в 08:50
поделиться

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

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

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

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

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

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

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

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

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

1
ответ дан 7 November 2019 в 08:50
поделиться

Прочтите здесь , чтобы узнать об ожидании и уведомлении.

Однако было бы лучше избегать их в ваших приложениях и использовать более новый java.util .concurrent пакет.

0
ответ дан 7 November 2019 в 08:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: