等待/通知和等待/中断有什么区别?

2023-11-28

synchronized (Foo.class) {
    while (someCondition) {
        try {
            Foo.class.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();            
        }
    }
}

看来这个线程在其他线程调用时都会被唤醒interrupt() or notify()在这个线程上。两者之间有什么区别吗?

--EDIT--

我知道一个用于通知对象,另一个用于中断线程。但这两种情况都会导致同样的后果,就是这个线程被唤醒,所以我想问的是这两种情况的后果有何不同。


当一个线程在某个监视器上调用notify时,它会唤醒正在该监视器上等待的单个线程,但是which线程被唤醒是由调度程序决定的。 (或者一个线程可以调用notifyAll,它会唤醒所有等待该监视器的线程,然后它们都争夺监视器,然后失败者继续等待。)这就是为什么调用的目标不同,发出通知到监视器,它告诉调度程序选择一个线程来唤醒。

与通知不同,中断针对特定线程。并且中断不需要被中断的线程在监视器上等待。对于要在监视器上调用 wait 的线程,它必须首先获取该监视器,然后 wait 释放该监视器,直到线程完成等待或被中断。

Oracle 的建议是仅在取消时使用中断。 java.util.concurrent 中的类也被设计为使用中断来取消。

在您的示例中,中断不会非常有效,因为控制不会离开 while 循环,线程仍然必须检查其正在等待的条件,并且 while 循环条件中不会检查是否设置了中断标志。被中断的线程很可能会立即返回等待状态。

为了使该代码在被中断后立即退出,而不是返回等待状态,请在循环条件中添加对中断标志状态的检查,并让 catch 块设置中断标志(抛出异常时该标志会重置):

synchronized (Foo.class) {
    while (someCondition && !Thread.currentThread().isInterrupted()) {
        try {
            Foo.class.wait();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();            
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

等待/通知和等待/中断有什么区别? 的相关文章

随机推荐