Java 为什么多次调用wait()不会引发异常?

Java 为什么多次调用wait()不会引发异常?,java,multithreading,wait,Java,Multithreading,Wait,我知道在不获取对象所有权的情况下调用wait方法会导致异常。 从Javadoc调用wait 线 *释放此监视器的所有权并等待另一个线程 *通知等待此对象监视器唤醒的线程 *通过调用{@code notify}方法或 *{@code notifyAll}方法。 所以,一旦对对象调用了wait,那个特定线程就会失去对该对象的所有权,直到其他线程通知它 为什么调用会等待两次而不通知,而不会抛出错误? 为了确保,…我只是运行了producer,所以没有其他线程的I在那里通知它,而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,是的。谢谢: