fhu*_*cho 9 java concurrency multithreading synchronized wait
例如:
public synchronized Object get() {
while (result == null) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
// Do we own the monitor of this object?
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
当e.printStackTrace()
执行,是我们保证自己的对象的显示器呢?
引用说当wait()
在一个notify()
或者notifyAll()
调用之后返回时,线程会等待它获取对象的监视器.但wait()
抛出异常时的情况呢?
等待返回时(包括它抛出InterruptedException的情况),线程必须有监视器,否则它不能在该synchronized方法中执行.线程必须先获取监视器才能离开wait方法.然后,一旦它离开wait方法,线程就有了监视器,并在线程离开方法时释放它.
这里最好将InterruptedException抛给调用者而不是吃掉它.你的目标是快速离开,让调用者知道发生了中断,这样就可以解决问题.在这里吃它也似乎意味着你再次回到while循环.java.util.concurrent使用中断来实现取消,特别是如果您使用java.util.concurrent工具,编写与它们兼容的代码是有意义的.
是的。事实上,这InterruptedException
是在重新获取监视器后抛出的。
请参阅jls 中的等待:
令线程 t 为对对象 m 执行 wait 方法的线程,令 n 为 t 对 m 的锁定操作(尚未与解锁操作匹配)的数量。发生以下操作之一:
如果 n 为零(即,线程 t 尚未拥有目标 m 的锁),则抛出 IllegalMonitorStateException。
如果这是定时等待并且 nanosecs 参数不在 0-999999 范围内或者 millisecs 参数为负数,则抛出 IllegalArgumentException。
如果线程 t 被中断,则会抛出 InterruptedException,并将 t 的中断状态设置为 false。
否则,将发生以下顺序:
线程t被添加到对象m的等待集中,并对m执行n次解锁操作。
线程 t 在从 m 的等待集中删除之前不会执行任何进一步的指令。由于以下任一操作,线程可能会从等待集中删除,并将在稍后恢复:
对 m 执行通知操作,其中选择 t 从等待集中删除。
正在 m 上执行的 notificationAll 操作。
正在 t 上执行中断操作。
如果这是定时等待,则自该等待操作开始以来至少经过 millisecs 毫秒加上 nanosecs 纳秒后发生从 m 的等待集中删除 t 的内部操作。
实施的内部行动。尽管不鼓励,但允许实现执行“虚假唤醒”,即从等待集中删除线程,从而在没有明确指令的情况下启用恢复。
线程 t 对 m 执行 n 次锁定操作。
如果线程 t 在步骤 2 中因中断而从 m 的等待集中移除,则 t 的中断状态将设置为 false,并且 wait 方法将抛出 InterruptedException。
归档时间: |
|
查看次数: |
195 次 |
最近记录: |