【问题标题】:Java wait() not Throwing InterruptedExceptionJava wait() 不抛出 InterruptedException
【发布时间】:2011-05-19 06:14:16
【问题描述】:

我在 thread A 上有一个对象正在调用 wait(),而 thread B 上的另一个对象做了一些工作然后调用 thread A的对象的notify()。然后线程 A 执行一些后处理。

我的问题很简单:

synchronized(this)
{
    while(!flag)
    {
        try
        {
            wait();
            getLogger().info("No longer waiting");
        }
        catch (InterruptedException ie)
        {
            getLogger().info("Wait threw InterruptedException");
        }
    }
}

导致“不再等待”而不是“等待引发 InterruptedException”的信息消息。

我很困惑,因为这个 (http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#wait()):

抛出:

InterruptedException - 如果另一个线程中断了 当前线程在当前线程等待之前或期间 通知。当前线程的中断状态被清除 什么时候抛出这个异常。

为什么我会有奇怪的行为?

谢谢。

【问题讨论】:

  • 另一个线程在您的对象上调用 notify 不符合中断条件。

标签: java concurrency synchronization wait notify


【解决方案1】:

当一个线程使用wait() 等待时,他实际上是在等待notify()。所以一旦notify()被另一个线程调用,这个线程就会继续,如果你调用interrupt(),你会得到异常。

另外,从您链接到的文档中:

使当前线程等待直到 另一个线程调用 notify() 方法或 notifyAll() 方法 这个对象

notify从锁中释放线程。

InterruptedException - 如果另一个 线程中断了当前线程 在当前线程之前或期间 等待通知。

 

【讨论】:

  • 谢谢,我假设 notify() 导致 wait() 抛出 InterruptedException。
【解决方案2】:

notify() 不会使 wait() 抛出 InterruptedExceptionnotify()wait()继续正常的程序流程。

【讨论】:

    【解决方案3】:

    notify() 不是wait()-ing 线程的异常终止。例如,如果线程在调用 notify() 之前终止 - 不是因为调用 notify() 导致的,则会出现异常。线程没有被中断——它已经被唤醒了。

    【讨论】:

      【解决方案4】:

      请注意,您在该代码中存在错误。等待应始终在循环中调用,并在唤醒后检查条件。

      wait 可以被虚假唤醒唤醒。请参阅 javadoc wait()

      【讨论】:

      • 鉴于我们没有看到代码的任何上下文,您无法判断它有错误。它也不在同步块中,但我假设某处有一个。
      • @Jon Skeet。原始帖子没有带条件的循环,OP 说“线程 A 然后执行一些后处理”。这意味着他想等到另一个线程完成处理。由于虚假唤醒,没有条件检查的等待是一个错误。线程可以在没有通知的情况下被唤醒,然后在另一个线程完成之前开始后处理。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-26
      • 2010-11-08
      • 1970-01-01
      • 2020-09-27
      • 1970-01-01
      • 2014-10-09
      • 1970-01-01
      相关资源
      最近更新 更多