我们可以有虚假的中断吗?

时间:2017-11-08 09:01:07

标签: java multithreading

我正在创建一个每分钟查找任务的任务轮询器。它看起来像这样:

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()代替while (condition) { ... }来保护if (condition) { ... }。是否还会发生JVM会无缘无故地中断正在进行的线程?

在这种情况下,我应该引入一个volatile boolean并检查一下而不是while (!Thread.currentThread().isInterrupted())

1 个答案:

答案 0 :(得分:2)

是的,您应该引入volatile boolean来控制循环。不仅因为可能存在虚假中断,还因为它使代码更具可读性。

你没有通过“保存”boolean并使用线程的中断状态来控制循环来实现聪明的优化,你对这个类的工作机制不太明显是

编辑:我并没有真正回答核心问题(混淆了唤醒)。我们知道,spurious wakeups可以而且确实发生了,这就是为什么我们使用保护子句/循环来检查条件是否真的满足。

虚假中断不是一件事,这意味着总是有一个线程在Java生态系统内部中断另一个线程(与唤醒不同,其原因是外部的)。中断随机线程不是Java平台本身所做的事情,但是您可以编写一个线程,只是随机选择其他线程并尝试中断它们。然而,这不会是一个虚假的中断,那将是恶意中断。