waitpublic final voidwait(long timeout) throws
当前的线程必须拥有此对象监视器。
此方法导致当前线程(称之为T)将其自身放置在对象的等待集中,然后放弃此对象上的所有同步要求。出于线程调度目的,线程
T被禁用,且处于休眠状态,直到发生以下四种情况之一:
- 其他某个线程调用此对象的notify方法,并且线程T碰巧被任选为被唤醒的线程。
- 其他某个线程调用此对象的notifyAll方法。
- 其他某个线程线程
T。 - 已经到达指定的实际时间。但是,如果timeout为零,则不考虑实际时间,该线程将一直等待,直到获得通知。
然后,从对象的等待集中删除线程
T,并重新进行线程调度。然后,该线程以常规方式与其他线程竞争,以获得在该对象上同步的权利;一旦获得对该对象的控制权,该对象上的所有其同步声明都将被还原到以前的状态
- 这就是调用
wait方法时的情况。然后,线程
T从
wait方法的调用中返回。所以,从
wait方法返回时,该对象和线程
T的同步状态与调用
wait方法时的情况完全相同。
在没有被通知、中断或超时的情况下,线程还可以唤醒一个所谓的虚假唤醒(spurious
wakeup)。虽然这种情况在实践中很少发生,但是应用程序必须通过以下方式防止其发生,即对应该导致该线程被提醒的条件进行测试,如果不满足该条件,则继续等待。换句话说,等待应总是发生在循环中,如下面的示例:
synchronized (obj) { while (<condition does not hold>) obj.wait(timeout); ... // Perform action appropriate to condition }(有关这一主题的更多信息,请参阅
Doug Lea 撰写的《Concurrent Programming in Java (Second Edition)》(Addison-Wesley,
2000) 中的第 3.2.3 节或 Joshua Bloch 撰写的《Effective Java Programming Language
Guide》(Addison-Wesley, 2001) 中的第 50 项。
如果当前线程在等待时被其他线程,则会抛出
InterruptedException。在按上述形式恢复此对象的锁定状态时才会抛出此异常。
注意,由于wait
方法将当前的线程放入了对象的等待集中,所以它只能解除此对象的锁定;可以同步当前线程的任何其他对象在线程等待时仍处于锁定状态。
此方法只应由作为此对象监视器的所有者的线程来调用。请参阅 notify 方法,了解线程能够成为监视器所有者的方法的描述。
参数:
timeout - 要等待的最长时间(以毫秒为单位)。
抛出:
- 如果超时值为负。
- 如果当前的线程不是此对象监视器的所有者。
- 如果在当前线程等待通知之前或者正在等待通知时,另一个线程中断了当前线程。在抛出此异常时,当前线程的
中断状态被清除。