wait() 总是抛出 InterruptedException。

3
以下的wait()调用总是抛出InterruptedException。并不是其他线程在中断它。调用和异常被抛出之间没有延迟。我已经添加了日志来检查调用和异常捕获之间的时间差。
另外,Thread.sleep(long)也会得到相同的结果。
public synchronized void retryConnection()
{
// . .. some code
    try
    {
        wait();
    }
    catch(InterruptedException e)
    {
        log(Level.SEVERE, "InterruptedException " , e);
    }
// . .. some code
}

我尝试了以下方法:

在新线程中调用此方法。然后它可以正常工作。这是一种等待和通知机制。

将相同的代码再次放置,即在捕获异常后再次等待。然后它会正确地等待。

观察:当调用来自netty(服务器)线程时,它会失败,但如果来自其他Java线程,则可以正常工作。因此我的问题是:是否有任何机制或线程状态,在该状态下调用wait()Thread.sleep()是被禁止的,并且如果调用它们则会抛出异常?

我已经检查了中断标志,它始终为“false”。

1个回答

2

InterruptedException在使用Object.wait(),以及将thread.sleep()Object.notify()Object.notifyAll()结合使用时是一种完全正常的事件。

这被称为线程间通信

拥有对象监视器的线程可以调用Object.wait(),这会导致当前线程失去监视器的所有权并等待/阻塞,直到另一个拥有该对象监视器的线程调用Object.notify()Object.notifyAll()

这意味着拥有锁的活动线程会唤醒其他等待(或睡眠、阻塞)状态的线程。在通知到达之前,原始线程还必须放弃对对象锁的控制,以便接收到通知的线程可以继续进行。

正在等待锁的线程将通知作为InterruptedException接收。然后它可以继续进行,因为在接收到异常时,它已经获得了锁的所有权。

请查看Java线程生命周期图表以获取更多信息
所以在您的情况下:
- 接收InterruptedException并不是失败。 - Netty试图提高性能,不会让线程等待太久,因此您不断收到通知。 - 当您运行线程时,未调用notify()或notifyAll(),因此不会抛出异常。 - 对于Object.wait()和Thread.sleep(),您将获得以下内容(来自javaDoc):
“当抛出此异常时,当前线程的中断状态被清除。”

1
我知道这非常老旧,但如果您想继续等待,该怎么办? - SMBiggs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接