调用wait()方法时发生了什么

时间:2019-02-11 03:17:51

标签: java multithreading

我在Java教科书中阅读了以下与多线程有关的内容。

  

对于要调用wait()或notify()的线程,该线程必须是该对象的锁的所有者。什么时候   线程等待,它会暂时释放锁供其他线程使用,但是这需要   再次执行以继续执行。

我对条款

的含义感到困惑
  

当线程等待时,它会暂时释放其他线程的锁   使用的线程

我不明白该条款在说什么。是否表示在调用wait()方法时,它实际上是在wait()返回之前释放了锁(即,这种情况是在调用者不知道的情况下发生的)?还是只是暗示wait(timeout)超时后释放锁?如果是前者,为什么会在notify()之前释放锁?这似乎是一个模糊且解释不清的声明。

3 个答案:

答案 0 :(得分:1)

当线程调用等待时,该线程立即释放锁定,然后进入休眠状态,直到超时到期(如果有)或直到接收到通知为止,该通知发生在另一个线程获得与等待线程相同的锁定时并调用通知(调度程序也必须从其他所有等待线程中选择等待线程;调用notify不会通知给定线程,它告诉调度程序从给定锁的等待集中选择一个线程进行通知) 。

一旦线程被通知唤醒,它必须重新获取锁才能退出等待方法,因为线程仍处于同步方法或块内。那就是当引用说线程将需要锁来恢复执行时的意思。

答案 1 :(得分:1)

对于要调用wait()或notify()的线程,该线程必须是该对象的锁的所有者。

否则,会发生运行时错误,并且其余代码不会执行。

当线程等待时,它会暂时释放锁定以供其他线程使用

更多信息,请调用 wait()执行以下操作:

  • 锁被释放
  • 当前线程在监视器中注册为等待中
  • 处理器切换到准备执行的其他线程

然后,某些线程调用 notify() notifyAll(),这将导致一个或所有在此监视器上注册为等待的线程从等待状态中移出。设置为就绪状态,等待空闲处理器执行。

,但是它将再次需要它来继续执行。

这意味着线程的执行将继续执行 synchronized 语句以重新获得锁。获取锁定后,将返回 wait()方法。 wait(timeout)的不同之处在于,除了 notify() notifyAll(),它也可以在超时后返回。

总而言之,您需要了解线程如何在以下4种状态之间切换:

  • 在处理器上运行
  • 同步语句上被阻止
  • 等待通知
  • 准备执行并等待免费处理器

答案 2 :(得分:1)

当线程调用wait()时,它将暂时释放对象的监视器(锁),直到它从另一个线程接收到通知为止。这样,线程可以将对象监视器的控制权(首先是它的控制权)交给另一个线程。看看docs

  

直到另一个线程具有wait()的调用才会返回   发出了可能发生某些特殊事件的通知-   尽管不一定是该线程正在等待的事件(所以总是   在测试条件的循环内调用wait()   等待)。

     

...

     

调用wait()时,线程释放锁并挂起   执行。在将来的某个时间,另一个线程将获得相同的   锁定并调用Object.notifyAll,通知所有正在等待的线程   那个重要事情已经发生的锁。