我正在创建一个任务轮询器,每分钟都会查找任务。它看起来像这样:
public class Poller {
private final ExecutorService e = Executors.newSingleThreadExecutor();
public void start() {
e.submit(() -> {
while (!Thread.currentThread().isInterrupted()) {
final Task task = manager.getTask();
if (task != null) {
// ...
} else {
try {
TimeUnit.MINUTES.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
});
}
public void stop() {
e.shutdownNow();
}
}
当我想停止电源过程时,我执行stop()
。这会触发正在运行的线程上的中断,这将停止轮询器。
这很好用。但是,我想知道该线程是否有可能被中断其他人,很可能是 JVM。在这种情况下,轮询器将退出,而它不应该退出。
我知道我们可能会出现虚假唤醒,所以我们必须警惕wait()
with a while (condition) { ... }
代替if (condition) { ... }
。 JVM 是否也会无缘无故地中断正在进行的线程?
在这种情况下,我应该介绍一个volatile boolean
并检查它而不是while (!Thread.currentThread().isInterrupted())
?
是的,你应该介绍一个volatile boolean
来控制循环。不仅仅是因为可能出现虚假中断,还因为它使代码更具可读性。
您并没有通过“保存”来实现聪明的优化boolean
并使用线程的中断状态来控制循环,使类的工作机制变得不那么明显。
编辑:我并没有真正回答核心问题(将其与唤醒混合在一起)。据我们所知,虚假唤醒 https://stackoverflow.com/questions/1050592/do-spurious-wakeups-actually-happen可以并且确实会发生,这就是为什么我们使用保护子句/循环来检查条件是否确实得到满足。
虚假中断不是一回事,这意味着在 Java 生态系统中总是有一个线程会中断另一个线程(与唤醒不同,唤醒的原因是外部的)。中断随机线程不是 Java 平台本身执行的操作,但您可以编写一个线程,随机选择其他线程并尝试中断它们。然而,这不会是一个虚假的中断,那将是一个恶意的打断。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)