线程中断()不会中断线程

时间:2014-05-07 11:11:15

标签: java multithreading interrupt

出于某种原因,当迭代一个线程列表并中断所有线程时,它们都没有用InterruptedException执行catch块。

在以下存储库中:https://github.com/ranisalt/LiuThread

我有两个线程,每个线程都有执行器服务,其中一个拥有读者,另一个读取编写器。写入者应该每隔100毫秒产生一次,写入缓冲区并退出/停止/不管再做什么。读者是4个尝试阅读的主题,如果可以,他们也应该退出,所以还有其他读者的空间。

我有100个(读者和作者),如果他们无法读写,他们会等待60秒。

然后,我有一个协调器线程,它继续测试缓冲区是否为空(并中断编写器)或完全(中断读取器),因此它们永远不应该等待60秒。缓冲区知道它的状态。

问题是,出于某种原因,这个片段:

for (ThreadAzul azul : threadsAzuis) {
    azul.interrupt();
}

不打断线程!我用println看看是否被打断了:

try {
    sleep(60000);
    System.out.println(this.getName() + " foi dormir");
} catch (InterruptedException e) {
    System.out.println(this.getName() + " foi interrompido");
}

但是这绝不会写。 interrupt()没有使catch块执行的原因是什么?

3 个答案:

答案 0 :(得分:4)

在您main上调用run() Thread方法内部,因此您永远不会开始新的Thread,而是在初始main内运行其代码线。因此,在您从未启动的interrupt实例上调用Thread不会中断实际执行代码的main线程。

submit Thread个实例发送到Executor时,会再次出现同样的错误。执行程序将执行run实例的Thread方法,因为Thread实现了Runnable,但Executor将在其自己的托管Thread内执行但不是在您创建但从未开始的实例所代表的Thread范围内。

所以再一次,在你从未启动的interrupt实例上调用Thread将不会中断实际执行代码的线程。

通常,您应不要混用 ThreadExecutor。决定采用一种方式,手动处理Thread或使用ExecutorSevice s。

当您使用Thread时,必须使用start()方法启动它们,而不是调用run()方法。

答案 1 :(得分:1)

线程仅在可中断操作期间被中断,例如Thread.sleep(), Thread.wait(),和一些I / O调用(不是全部)。

答案 2 :(得分:0)

设置中断标志,不会中断线程。线程在检查时结束,如果它应该结束。因此,只需让线程有机会检查 isInterrupted(),或在休眠或等待时中断它。 如果在 run()中有长期方法,则 interrupt()将不起作用。您必须实施定期检查或其他解决方法。