调用wait函数后如何判断哪个线程会等待?

时间:2017-06-13 03:47:41

标签: java multithreading

在Java多线程中,可以在任何对象上调用wait方法。我们怎么知道哪个对象会等待?

E.g:

  1. 我创建了一个线程并在该线程的run方法中声明了obj.wait(),其中obj是该线程类中使用的某个对象。当我们从主线程中调用thread.start方法哪个线程会等待?

  2. 在另一个场景中,如果我从main调用它而不是调用wait内部的run方法,如t.wait(),其中t是线程方法实例,那么哪个线程将wait()?

  3. 第一种和第二种情况是否相同?

    1. 或者如果我从main调用obj.wait()而不是从main调用t.wait(),其中obj是main方法中的某个对象,那么哪个线程会等待?
    2. 有人可以解释这个概念,因为有很多种方法可以从不同的上下文和不同的对象调用wait吗?

2 个答案:

答案 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}}调用,检查是否有这种情况已经满足了。