在线程上调用interrupt(),但它从不中断

时间:2012-01-22 08:31:32

标签: java multithreading interrupt

我编写了VideoProcessor类,它对视频进行了一些繁重的处理。如果“已启动”,则创建一个新的线程,并将引用保存在 videoProcessingThread 字段中。现在的问题是:

videoProcessingThread.interrupt();

这似乎没有任何影响,因为isInterrupted()永远不会评估为true。我还添加了其他中断检查,只是为了确定;但他们也没有“工作”。我已经实施了一个解决方法:

videoProcessingThread.kill();

这似乎实际上是“杀死”线程。方法kill将布尔变量 kill 设置为true,并且正确计算并返回Thread。

videoProcessingThread = new Thread() {
    boolean kill = false; // workaround 

    public void run() {
        // init stuff
        while (currentFrameIndex < totalFrames) {
            if (isInterrupted()) { 
                System.out.println("isInterrupted");

                return;
            }
            if (Thread.interrupted()) {
                System.out.println("interrupted");

                return;
            }
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("Thread.currentThread().isInterrupted()");

                return;
            }
            if (kill) {
                System.out.println("killed");

                return;
            }
        }
        // heavy processing
    }

    public void kill() {
        kill = true;
    }
}

我做错了什么?

2 个答案:

答案 0 :(得分:1)

您的kill无法保证正常工作,除非其不稳定。

只有在调用检查此标志的操作被调用时,才会中断线程。如果您拨打interrupt()

,一些NIO操作会抛出异常

大部分时间使用interrupt()与设置易失性标志相同。即你的任务需要定期检查。杀死线程的唯一安全方法是在自己的进程中运行它。

如果你有一个作为Actor的线程(它只修改线程本地内存),你可以考虑使用stop()。它的主要问题是你可以将内存修改为一个不一致的状态。如果您隔离该线程的内存并在线程停止时将其丢弃,这应该可以正常工作。

答案 1 :(得分:1)

首先,调用interrupt()可能实际上并未设置中断状态,请参阅here in javadocs确切的条件,有时只会抛出InterruptedException

其次,除了返回之外,实际调用interrupted()方法还会清除中断状态,因此下次调用isInterrupted()(仅返回当前状态) ,但不清楚它可能不会做你期望的。

使用布尔变量可能不是一个不好的方法来实现这一点。您可以阅读this article,其中介绍了一些细节,以阐明当您尝试中断线程以及如何或多或少地可靠地执行该操作时会发生什么。