天天看點

Java正确處理InterruptedException的方法

要想讨論正确處理InterrupedtException的方法,就要知道InterruptedException是什麼。

根據Java Doc的定義

Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity. Occasionally a method may wish to test whether the current thread has been interrupted, and if so, to immediately throw this exception.

意思是說當一個線程處于等待,睡眠,或者占用,也就是說阻塞狀态,而這時線程被中斷就會抛出這類錯誤。Java6之後結束某個線程A的方法是 A.interrupt()。如果這個線程正處于非阻塞狀态,比如說線程正在執行某些代碼的時候,不過被interrupt,那麼該線程的 interrupt變量會被置為true,告訴别人說這個線程被中斷了(隻是一個标志位,這個變量本身并不影響線程的中斷與否),而且線程會被中斷,這時 不會有interruptedException。但如果這時線程被阻塞了,比如說正在睡眠,那麼就會抛出這個錯誤。請注意,這個時候變量 interrupt沒有被置為true,而且也沒有人來中斷這個線程。比如如下的代碼:

while(true){
    try {
     Thread.sleep(1000);
    }catch(InterruptedException ex)
    {
          logger.error("thread interrupted",ex);
    } 
}

           

當線程執行sleep(1000)之後會被立即阻塞,如果在阻塞時外面調用interrupt來中斷這個線程,那麼就會執行

logger.error("thread interrupted",ex);
           

這個時候其實線程并未中斷,執行完這條語句之後線程會繼續執行while循環,開始sleep,是以說如果沒有對InterruptedException進行處理,後果就是線程可能無法中斷

是以,在任何時候碰到InterruptedException,都要手動把自己這個線程中斷。由于這個時候已經處于非阻塞狀态,是以可以正常中斷,最正确的代碼如下:

while(!Thread.isInterrupted()){
    try {
     Thread.sleep(1000);
    }catch(InterruptedException ex)
    {
          Thread.interrupt()
    } 
}
           

這樣可以保證線程一定能夠被及時中斷。

對于更為複雜的情況,除了要把自己的線程中斷之外,還有可能需要抛出InterruptedException給上一層代碼