0

我想创建一个可以随时中断的线程,同时防止虚假唤醒。这里的问题是虚假唤醒和中断的工作方式相同:它们抛出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没有。我看到的唯一可能的解决方案是为volatile boolean每个线程使用一些额外的东西,但这Thread.interrupt()本身就变得毫无用处。

4

1 回答 1

3

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

这不是我的理解。 虚假唤醒的发生是因为一个条件在没有被特别发出信号的情况下被唤醒,并且与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较少使用循环来处理虚假的唤醒条件(这有点罕见),而更多地用于线程竞争条件

于 2022-02-15T18:32:54.897 回答