2011-02-05 44 views

回答

110

這樣做是爲了保持狀態

當你趕上InterruptException把它吞了,你基本上是防止任何更高級別的方法/線程組注意不到中斷。這可能會導致問題。

通過調用Thread.currentThread().interrupt(),您設置線程的中斷標誌,所以更高級別中斷處理程序會注意到這一點,並能妥善處理這個問題。

Java Concurrency in Practice中對此進行了更詳細的討論第7.1.3章:響應中斷。它的規則是:

只有實現線程中斷策略的代碼才能吞下中斷請求。通用任務和庫代碼不應該吞服中斷請求。

+7

在[documentation](https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html)中聲明_「按照慣例,任何通過拋出一個`InterruptedException`退出的方法**清除中斷狀態**當它這樣做。我認爲這使得答案更清晰_why_你需要保持中斷狀態。 – 2016-02-04 13:52:22

2

我會認爲這是一個不好的做法,或至少有點冒險。 通常更高級別的方法不會執行阻止操作,並且它們在此處永遠不會看到InterruptedException。如果你在每個執行可中斷操作的地方都將其掩蓋起來,你永遠不會得到它。

Thread.currentThread.interrupt()和不加任何其它異常或以任何其他方式信號的中斷請求(例如,設置在一個線程中的主循環interrupted局部變量變量)的唯一理由是,你真的不能用異常做任何事情的情況,就像在finally塊中一樣。

遇見了彼得Török的答案,如果你想更好地瞭解Thread.currentThread.interrupt()呼叫的影響。

14

注:

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

如何停止等待很長時間線程(例如,用於輸入)?

對於這種技術的工作,它的關鍵,映入中斷異常,是不是準備好應對任何方法立即重新例外。我們說reasserts而不是rethrows,因爲它不總是可能重新拋出異常。 如果捕獲InterruptedException的方法沒有聲明拋出這個(選中)異常,那麼就應該「reinterrupt本身」具有以下咒語:

Thread.currentThread().interrupt(); 

這確保了主題將盡快重新調用InterruptedException。

45

我覺得這個代碼示例使事情變得有點清晰。 其中從事這項工作的類:

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(); 
     } 

    } 

嘗試調用中斷,而不設置狀態回來了。

+5

真棒例子,謝謝。 – Ben 2015-04-09 19:29:56

相關問題