为什么多次调用 wait() 不会抛出异常?
Why calling wait() more than once is not throwing Exceptions?
我知道在未获得对象所有权的情况下调用 wait()
方法会导致异常。
来自 Java 文档,调用 wait()
线程
* 释放此监视器的所有权并等待另一个线程
* 通知等待此对象监视器的线程唤醒
* 通过调用 {@code notify}
方法或
* {@code notifyAll}
方法。
因此,一旦在对象上调用 wait()
,该特定线程就会失去对该对象的所有权,直到其他线程通知它。
为什么在没有通知的情况下调用wait()
两次,没有抛出错误?
为了确保,..我只是 运行 生产者,所以没有其他线程在那里通知它并且 wait()
方法被无限次调用。
然而,尽管在第一次 wait()
调用后失去了所有权,但随后的等待调用应该抛出 exceptions.isn'?但为什么它工作正常?
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()
returns 在您的示例中,您再次锁定 queue
.
编辑:每次更新问题
因此,"calling wait()
twice without notifying" 是不可能的,因为第一次调用 wait()
将阻塞线程,直到收到通知。不能在循环中无限次调用,要么阻塞,要么抛异常。
加法:
顺便说一下,"naked" 等待通常是有风险的,因为无法保证哪个等待线程被唤醒(例如,生产者或消费者)。
一个常见的习语(如 Java "built-in monitors" -- synchronized
块 -- 没有条件变量)类似于
while(! condition)
wait();
在这种情况下,对于消费者来说,可能类似于
while(queue.isEmpty())
wait();
我知道在未获得对象所有权的情况下调用 wait()
方法会导致异常。
来自 Java 文档,调用 wait()
线程
* 释放此监视器的所有权并等待另一个线程
* 通知等待此对象监视器的线程唤醒
* 通过调用 {@code notify}
方法或
* {@code notifyAll}
方法。
因此,一旦在对象上调用 wait()
,该特定线程就会失去对该对象的所有权,直到其他线程通知它。
为什么在没有通知的情况下调用wait()
两次,没有抛出错误?
为了确保,..我只是 运行 生产者,所以没有其他线程在那里通知它并且 wait()
方法被无限次调用。
然而,尽管在第一次 wait()
调用后失去了所有权,但随后的等待调用应该抛出 exceptions.isn'?但为什么它工作正常?
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()
returns 在您的示例中,您再次锁定 queue
.
编辑:每次更新问题
因此,"calling wait()
twice without notifying" 是不可能的,因为第一次调用 wait()
将阻塞线程,直到收到通知。不能在循环中无限次调用,要么阻塞,要么抛异常。
加法:
顺便说一下,"naked" 等待通常是有风险的,因为无法保证哪个等待线程被唤醒(例如,生产者或消费者)。
一个常见的习语(如 Java "built-in monitors" -- synchronized
块 -- 没有条件变量)类似于
while(! condition)
wait();
在这种情况下,对于消费者来说,可能类似于
while(queue.isEmpty())
wait();