有什么好办法区分虚假唤醒和Thread.interrupt()?
Is there a good way to distinguish spurious wake up and Thread.interrupt()?
我想制作一个可以随时中断的线程,同时防止虚假唤醒。
这里的问题是虚假唤醒和中断的工作方式相同:它们抛出 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()
本身基本上没用。
spurious wakes as well as interrupts work the same: they throw InterruptedException
这不是我的理解。 Spurious wakeups 发生是因为在没有明确发出信号的情况下唤醒了一个条件,与 InterruptedException
无关。由于实现细节,当 any 条件发出信号时,某些线程系统会唤醒 all 条件。根据定义,虚假唤醒是我们需要 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。
我想制作一个可以随时中断的线程,同时防止虚假唤醒。
这里的问题是虚假唤醒和中断的工作方式相同:它们抛出 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()
本身基本上没用。
spurious wakes as well as interrupts work the same: they throw InterruptedException
这不是我的理解。 Spurious wakeups 发生是因为在没有明确发出信号的情况下唤醒了一个条件,与 InterruptedException
无关。由于实现细节,当 any 条件发出信号时,某些线程系统会唤醒 all 条件。根据定义,虚假唤醒是我们需要 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。