Java 为什么多次调用wait()不会引发异常?
我知道在不获取对象所有权的情况下调用wait方法会导致异常。 从Javadoc调用wait 线 *释放此监视器的所有权并等待另一个线程 *通知等待此对象监视器唤醒的线程 *通过调用{@code notify}方法或 *{@code notifyAll}方法。 所以,一旦对对象调用了wait,那个特定线程就会失去对该对象的所有权,直到其他线程通知它 为什么调用会等待两次而不通知,而不会抛出错误? 为了确保,…我只是运行了producer,所以没有其他线程的I在那里通知它,而wait方法被称为无限次。 然而,尽管在第一次等待调用后失去了对该调用的所有权,但随后的等待调用应该抛出异常。不是吗?但为什么它工作正常Java 为什么多次调用wait()不会引发异常?,java,multithreading,wait,Java,Multithreading,Wait,我知道在不获取对象所有权的情况下调用wait方法会导致异常。 从Javadoc调用wait 线 *释放此监视器的所有权并等待另一个线程 *通知等待此对象监视器唤醒的线程 *通过调用{@code notify}方法或 *{@code notifyAll}方法。 所以,一旦对对象调用了wait,那个特定线程就会失去对该对象的所有权,直到其他线程通知它 为什么调用会等待两次而不通知,而不会抛出错误? 为了确保,…我只是运行了producer,所以没有其他线程的I在那里通知它,而wait方法被称为无限次
class Producer extends Thread {
private Queue<Integer> queue;
private int maxSize;
public Producer(Queue<Integer> queue, int maxSize, String name) {
super(name);
this.queue = queue;
this.maxSize = maxSize;
}
public void run() {
while (true) {
synchronized (queue) {
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
如果您只运行该线程,它将在尝试添加调试输出后阻塞 等待阻塞,直到收到通知,并在返回前重新获取锁。即,在您的示例中,当等待返回时,您再次锁定了队列 编辑:每次问题更新 因此,在不通知的情况下调用wait两次是不可能的,因为对wait的第一次调用将阻塞线程,直到通知为止。它不能在循环中无限次调用,它要么阻塞,要么抛出异常 补充: 顺便说一句,裸等待通常是有风险的,因为无法保证哪一个等待线程被唤醒,例如,生产者或消费者。 Java内置监控器(同步块)没有条件变量的一个常见习惯用法是
while(! condition)
wait();
while(queue.isEmpty())
wait();
在这种情况下,对于消费者来说,可能类似
while(! condition)
wait();
while(queue.isEmpty())
wait();
你不止一次是什么意思?您是否从不同的线程调用上面的run方法?也许它是从您没有向我们展示的某个代码中调用的?如果这回答了您的问题,是的,您没有在这里循环,您正在调用等待一次,然后您的代码停止,直到通知或抛出异常为止。@Sriharsha,如果它回答了您的问题,请接受答案。如果没有,请澄清,我将尝试更新答案。@SRobertz,请更新你的答案,因为它没有指出我的问题,为什么不通知多次呼叫wait不会引发异常,所以有点不清楚。尽管如此,我还是从评论中得到了一点,那就是它并不是在循环,而是在等待得到通知。所以,当你们写下等待方法被称为无限次时,疑问就澄清了。这不应该发生。您是否已验证它是否与调试打印输出一起使用?如果是这样,您需要显示更多代码,因为这不应该发生。@SRobertz,是的。谢谢: