为什么在Java的Object类中声明了wait()和notify()?

Bhu*_*upi 53 java multithreading notify wait

为什么在类中声明wait()notify()方法Object而不是Thread类?

And*_*yle 42

因为,您在给定的Object(或特别是其监视器)上等待使用此功能.

我想你可能会误解这些方法是如何工作的.它们不仅仅处于线程粒度级别,即它不是仅仅wait()通过下次调用来调用和唤醒的情况notify().相反,您总是调用wait()特定对象,并且只会通过notify 对该对象的调用来唤醒.

这很好,因为否则并发原语就不会扩展; 它等同于拥有全局命名空间,因为notify()对程序中任何地方的任何调用都有可能弄乱任何并发代码,因为它们会唤醒任何阻塞wait()调用的线程.因此你在特定对象上调用它们的原因; 它为wait-notify对提供了一个上下文,因此当你myBlockingObject.notify()在私有对象上调用时,你可以确定你只会唤醒在你的类中调用wait方法的线程.一些可能在另一个对象上等待的Spring线程将不会被此调用唤醒,反之亦然.

编辑:或者从另一个角度解决这个问题-我从你的问题,你以为你会得到一个处理等待的线程,并呼吁希望notify()该线程将其唤醒.它没有这样做的原因是你必须自己做很多家务.要等待的线程必须在其他线程可以看到的地方发布对自己的引用; 这必须正确同步以强制一致性和可见性.当你想要唤醒一个线程时,你必须抓住这个引用,唤醒它,并从你读取它的任何地方删除它.与仅仅调用myObj.wait()睡眠线程然后myObj.notify()在waker线程中相比,涉及更多的手动脚手架,并且更多的机会出错(特别是在并发环境中).

  • 这并没有开始回答为什么你可以等待任何对象.为什么没有特定的Lock类或类型?或者也许是标记界面? (8认同)

小智 10

最简单明了的原因是任何Object(不仅仅是一个线程)都可以作为线程的监视器.在监视器上调用wait和notify.正在运行的线程检查监视器.所以wait和notify方法是在Object而不是Thread


Tay*_*ese 8

因为一次只有一个线程可以拥有对象的监视器,并且此监视器是线程正在等待或通知的内容.如果你读了的javadocObject.notify()Object.wait()它的详细描述.