1. 程式人生 > >Java正確處理InterruptedException的方法

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給上一層程式碼