【问题标题】:Is there a good way to distinguish spurious wake up and Thread.interrupt()?有什么好方法可以区分虚假唤醒和 Thread.interrupt() 吗?
【发布时间】:2022-02-16 02:51:44
【问题描述】:

我想创建一个可以随时中断的线程,同时防止虚假唤醒。 这里的问题是虚假唤醒和中断的工作方式相同:它们抛出InterruptedException

void anyMethodCalledByThread() {
  // .. a lot of work before
  while (wakingUpCondition) {
     try {
       lock.wait()
     } catch (InterruptedException e) {
       // is it spurious wake up and I should just ignore it?
       // or is it actual interrupt and I should do:
       // Thread.interrupt();
       // return;
       // and check interruption status in methods above to abort all tasks?
     }
  }
  // .. a lot of work after
}

据我所知,没有办法仅用jdk来区分它们,即使Condition属于no use。我看到的唯一可能的解决方案是每个线程使用一些额外的volatile boolean,但这使得Thread.interrupt() 本身基本上没有用。

【问题讨论】:

  • 您确定虚假唤醒会引发异常吗?

标签: java multithreading wait interrupt spurious-wakeup


【解决方案1】:

虚假唤醒和中断的工作方式相同:它们抛出 InterruptedException

这不是我的理解。 Spurious wakeups 发生是因为条件在没有被特别通知的情况下被唤醒,并且与 InterruptedException 无关。某些线程系统唤醒全部条件当任何由于实现细节而发出条件信号。根据定义,虚假唤醒是我们需要while 循环的原因之一。

如果wait() 方法抛出InterruptedException,那么它就真的被中断了。

// we use while loop because lock.wait() might return because of spurious wakeup
while (wakingUpCondition) {
   try {
      lock.wait()
   } catch (InterruptedException ie) {
      // if the wait was interrupted then we should re-interrupt and maybe quit
      Thread.currentThread().interrupt();
      // handle the interrupt by maybe quitting the thread?
      return;
   }
}

顺便说一句,我认为我们较少使用while 循环来处理虚假唤醒条件(这有点罕见),而更多用于thread race conditions

【讨论】:

    猜你喜欢
    • 2012-01-25
    • 1970-01-01
    • 2012-09-19
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 2022-06-16
    • 1970-01-01
    相关资源
    最近更新 更多