为什么在一个捕获InterruptException块中调用Thread.currentThread.interrupt()?
为什么在catch块中调用Thread.currentThread.interrupt()方法?
这是为了保持状态 。
当你捕获InterruptException
并且吞下它时,你基本上阻止了任何更高级的方法/线程组注意到这个中断。 这可能会导致问题。
通过调用Thread.currentThread().interrupt()
,可以设置线程的中断标志,所以更高级别的中断处理程序会注意到它,并且可以正确处理它。
实践中的Java Concurrency在 第7.1.3章“响应中断”中对此进行了更详细的讨论。 其规则是:
只有实现线程中断策略的代码才能吞下中断请求。 通用任务和库代码不应该吞下中断请求。
我认为这个代码示例使事情变得清晰一些。 做这个工作的class级:
public class InterruptedSleepingThread extends Thread { @Override public void run() { doAPseudoHeavyWeightJob(); } private void doAPseudoHeavyWeightJob() { for (int i=0;i<Integer.MAX_VALUE;i++) { //You are kidding me System.out.println(i + " " + i*2); //Let me sleep <evil grin> if(Thread.currentThread().isInterrupted()) { System.out.println("Thread interrupted\n Exiting..."); break; }else { sleepBabySleep(); } } } /** * */ protected void sleepBabySleep() { try { Thread.sleep(1000); } catch (InterruptedException e) { //e.printStackTrace(); Thread.currentThread().interrupt(); } } }
主要类别:
public class InterruptedSleepingThreadMain { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { InterruptedSleepingThread thread = new InterruptedSleepingThread(); thread.start(); //Giving 10 seconds to finish the job. Thread.sleep(10000); //Let me interrupt thread.interrupt(); } }
尝试调用中断而不设置状态。
注意:
如何停止等待很长时间的线程(例如,input)?
为了使这种技术起作用,捕获中断exception并且不准备立即处理它的任何方法重新确定exception是非常关键的。 我们说reasserts而不是rethrows,因为它不总是可能重新抛出exception。 如果捕获InterruptedException的方法没有被声明为抛出这个(checked)exception,那么它应该用下面的咒语“自我重新打开”:
Thread.currentThread().interrupt();
这可确保线程尽快重新调用InterruptedException。
我认为这是一个不好的做法,或者至less有点冒险。 通常更高级别的方法不会执行阻塞操作,并且不会在那里看到InterruptedException
。 如果你在每个执行可中断操作的地方都把它掩盖起来,你永远不会得到它。
Thread.currentThread.interrupt()
的唯一的基本原理,并不以任何其他方式引发任何其他exception或信号中断请求(例如,设置线程主循环中interrupted
局部variablesvariables)是你真的无法做任何事情的情况例外,就像在finally
块。
如果您想更好地理解Thread.currentThread.interrupt()
调用的含义,请参阅PéterTörök的答案。