在Java多线程中,可以在任何对象上调用wait方法。我们怎么知道哪个对象会等待?
E.g:
我创建了一个线程并在该线程的run方法中声明了obj.wait(),其中obj是该线程类中使用的某个对象。当我们从主线程中调用thread.start方法哪个线程会等待?
在另一个场景中,如果我从main调用它而不是调用wait内部的run方法,如t.wait(),其中t是线程方法实例,那么哪个线程将wait()?
第一种和第二种情况是否相同?
有人可以解释这个概念,因为有很多种方法可以从不同的上下文和不同的对象调用wait吗?
答案 0 :(得分:2)
调用obj.wait()
的线程是等待的线程。
...如果我从主要像t.wait()...
那样调用它
调用t.wait()
的威胁是等待的线程。对象的类型无关紧要。无论对象是线程还是任何其他类型的对象都无关紧要。调用wait()
的线程是等待的线程。
有人可以解释这个概念......?
Java教程做得非常好:
https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
更好:不要急于使用wait()
和notify()
。它们是低级基元,旨在以非常特定的方式(如教程中所示)用于构建更高级别的同步对象。但是Java库和第三方库已经提供了您需要的大多数同步对象的高质量实现。
如果您的目标是解决某些特定问题,那么不要浪费时间重新发明轮子。 OTOH,如果您的目标是了解轮子是如何构建的,那么这是一件好事!
答案 1 :(得分:1)
当你调用obj.wait()
时,它总是当前线程(即运行调用obj
的方法的线程)被挂起。只有当另一个线程在object.notify()
上同步,然后调用object.notifyAll()
或obj
,然后退出obj
上的同步块并因此释放其锁定时,它才会被恢复监控。
当第一个线程恢复时,它将首先重新获得obj.wait()
上的锁定。 (您只能在obj
上同步时调用wait()
,否则它将GitHub page。在线程等待时释放该锁定,并在线程唤醒之前重新获取。 )
在Thread实例上调用t.wait()
不是专门处理的,你不应该使用它,因为Thread已经使用它了。特别是notify()
不会导致该线程等待,而是导致当前线程等待,直到其他人在该Thread对象上同步并在其上调用notifyAll()
或wait()
,如上所述。问题是Thread使用这些方法用于它自己的目的,例如throw an IllegalMonitorStateException
。通过在Thread的实例上调用这些方法,您将有效地试图大喊自己的消息,这可能会导致问题。正如Thread的文档所说:
建议应用程序不要在Thread实例上使用wait,notify或notifyAll。
*线程也可以自行唤醒,这称为虚假唤醒;但这种情况非常罕见,虽然你应该反对它,但你永远不应该认为它会发生。特别是,因为你可能会调用wait()
来暂停你的线程,直到满足某些条件(另一个线程设置一些变量等),你应该总是在一个循环中包围{{1}}调用,检查是否有这种情况已经满足了。