出于某种原因,当迭代一个线程列表并中断所有线程时,它们都没有用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块执行的原因是什么?
答案 0 :(得分:4)
在您main
上调用run()
Thread
方法内部,因此您永远不会开始新的Thread
,而是在初始main
内运行其代码线。因此,在您从未启动的interrupt
实例上调用Thread
不会中断实际执行代码的main
线程。
当submit
Thread
个实例发送到Executor
时,会再次出现同样的错误。执行程序将执行run
实例的Thread
方法,因为Thread
实现了Runnable
,但Executor
将在其自己的托管Thread
内执行但不是在您创建但从未开始的实例所代表的Thread
范围内。
所以再一次,在你从未启动的interrupt
实例上调用Thread
将不会中断实际执行代码的线程。
通常,您应不要混用 Thread
和Executor
。决定采用一种方式,手动处理Thread
或使用ExecutorSevice
s。
当您使用Thread
时,必须使用start()
方法启动它们,而不是调用run()
方法。
答案 1 :(得分:1)
线程仅在可中断操作期间被中断,例如Thread.sleep(),
Thread.wait(),
和一些I / O调用(不是全部)。
答案 2 :(得分:0)
设置中断标志,不会中断线程。线程在检查时结束,如果它应该结束。因此,只需让线程有机会检查 isInterrupted(),或在休眠或等待时中断它。 如果在 run()中有长期方法,则 interrupt()将不起作用。您必须实施定期检查或其他解决方法。