为什么在一个捕获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(); } } 

尝试调用中断而不设置状态。

注意:

http://download.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

如何停止等待很长时间的线程(例如,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的答案。