2010-07-02 28 views
9

我正在使用CountDownLatch來同步兩個線程之間的初始化過程,我想知道它可能拋出的InterruptedException的正確處理方法。CountDownLatch InterruptedException

我最初寫的代碼是這樣的:

private CountDownLatch initWaitHandle = new CountDownLatch(1); 
    /** 
    * This method will block until the thread has fully initialized, this should only be called from different threads Ensure that the thread has started before this is called. 
    */ 
    public void ensureInitialized() 
    { 
     assert this.isAlive() : "The thread should be started before calling this method."; 
     assert Thread.currentThread() != this, "This should be called from a different thread (potential deadlock)"; 
     while(true) 
     { 
      try 
      { 
       //we wait until the updater thread initializes the cache 
       //that way we know 
       initWaitHandle.await(); 
       break;//if we get here the latch is zero and we are done 
      } 
      catch (InterruptedException e) 
      { 
       LOG.warn("Thread interrupted", e); 
      } 
     } 
    } 

這種模式是否有意義?基本上忽略InterruptedException只是一直等到它成功是一個好主意。我想我只是不明白這種情況會中斷,所以我不知道我是否應該以不同的方式處理它們。

爲什麼一個InterruptedException在這裏得到拋出,什麼是處理它的最佳做法?

回答

9

這就是你不應該爲InterruptedException做什麼。 InterruptedException基本上是該線程終止的禮貌請求。線程應該儘快清理並退出。

IBM有一個很好的文章上發佈有關此:http://www.ibm.com/developerworks/java/library/j-jtp05236.html

這裏是我會做:

// Run while not interrupted. 
while(!(Thread.interrupted()) 
{ 
    try 
    { 
     // Do whatever here. 
    } 
    catch(InterruptedException e) 
    { 
     // This will cause the current thread's interrupt flag to be set. 
     Thread.currentThread().interrupt(); 
    } 
} 

// Perform cleanup and exit thread. 

到做這種方式的優點是這樣的:如果你的線程而阻塞中斷方法,中斷位將不會被設置,而是引發InterruptedException。如果你的線程在沒有阻塞方法的情況下被中斷,被中斷的位將被設置,並且不會拋出異常。因此,通過調用interrupt()來設置異常標誌,兩種情況都被標準化爲第一種情況,然後由循環條件進行檢查。

作爲額外的獎勵,這也可以讓你通過簡單地將其中斷,而不是你自己發明的機制或接口設置一些布爾標誌,做同樣的事情阻止你的線程。

+0

嘎我試圖修復你的格式,並做了編輯衝突。我沒有選擇回滾。抱歉! – 2010-07-02 19:18:00

+0

我已經回滾了。感謝您的幫助!我注意到它是錯誤的,但決定在寫下文字牆的同時修復它。 – jdmichal 2010-07-02 19:19:19

+0

實際上不是,我只是真正習慣了維基百科,在那裏你點擊回滾你想撤消的編輯,而不是你想要回滾的修訂**到**。 – 2010-07-02 19:19:31

2

如果沒有預見到Thread可能被中斷任何正當理由,並不能認爲任何合理的反應,我說你應該做的

catch (InterruptedException e){ 
     throw new AssertionError("Unexpected Interruption",e); 
} 

這樣的應用程序將如果發生這種中斷,顯然會失敗,從而更容易在測試過程中發現。然後,您可以考慮應用程序如何處理該問題,或者如果他們在設計中遇到任何問題。