wait 等待方法是让线程进入等待队列, 使用方法是 obj.wait(); 这样当前线程就会暂停运行, 并且进入 obj 的等待队列中, 称作 "线程正在 obj 上等待".
如果线程想执行 wait 方法, 线程必须拥有锁. 如果线程进入等待队列, 就会释放其实例的锁.
有两种形式的 wait 方法
一种是: 接受毫秒数作为参数, 含义与 sleep 中方法里接受参数的意思相同, 都是指 "在此期间暂停", 但是与 sleep 方法不同的是, wait 在暂停等待期间, 对象锁是释放的, 而 sleep 是拥抱着这把锁; 还有一点不同的是, wait 方法可以通过 notify,notifyAll 或者等待的时间到期, 都可以令此线程接着执行.(时间参数值必须大于 0, 如果小于 0, 则会抛出 IllegalArgumentException 运行异常, 如果时间参数为 0 , 则会一直等待下去)
在接收参数的 wait 方法中, 有两种分别是:
- public final void wait(long timeout) throws InterruptedException
- public final void wait(long timeout,int nanos)throws InterruptedException
- public final void wait(long timeout, int nanos) throws InterruptedException {
- if (timeout <0) {
- throw new IllegalArgumentException("timeout value is negative");
- }
- if (nanos < 0 || nanos> 999999) {
- throw new IllegalArgumentException(
- "nanosecond timeout value out of range");
- }
- if (nanos>= 500000 || (nanos != 0 && timeout == 0)) {
- timeout++;
- }
- wait(timeout);
- }
wait(long timeout, int nanos) 在 Object 中的显示
另一种是: wait 方法不接受任何参数, 这种 wait(), 将无限等待下去, 直到线程接收到 nofity 或者 notifyAll 的通知信息, 才能继续执行.
摘自 JDK 的 API:
在没有被通知, 中断或超时的情况下, 线程还可以唤醒一个所谓的虚假唤醒 (spurious wakeup). 虽然这种情况在实践中很少发生, 但是应用程序必须通过以下方式防止其发生, 即对应该导致该线程被提醒的条件进行测试, 如果不满足该条件, 则继续等待. 换句话说, 等待应总是发生在循环中, 如下面的示例:
- synchronized (obj) {
- while (<condition does not hold>)
- obj.wait(timeout);
- ... // Perform action appropriate to condition
- }
如果在当前线程等待通知之前或者正在等待通知时, 任何线程中断了当前线程. 在抛出此异常时, 当前线程的中断状态被清除, 就会抛出中断异常 InterruptedException
来源: http://www.bubuko.com/infodetail-3005420.html