1. 程式人生 > >Java執行緒中斷理解(interrupte)

Java執行緒中斷理解(interrupte)

         Java執行緒之中,一個執行緒的生命週期分為:初始、就緒、執行、阻塞以及結束。當然,其中也可以有四種狀態,初始、就緒、執行以及結束。

         一般而言,可能有三種原因引起阻塞:等待阻塞、同步阻塞以及其他阻塞(睡眠、jion或者IO阻塞);對於Java而言,等待阻塞是呼叫wait方法產生的,同步阻塞則是由同步塊(synchronized)產生的,睡眠阻塞是由sleep產生的,jion阻塞是由jion方法產生的。

         言歸正傳,要中斷一個Java執行緒,可呼叫執行緒類(Thread)物件的例項方法:interrupte();然而interrupte()方法並不會立即執行中斷操作;具體而言,這個方法只會給執行緒設定一個為true的中斷標誌(中斷標誌只是一個布林型別的變數

),而設定之後,則根據執行緒當前的狀態進行不同的後續操作。如果,執行緒的當前狀態處於非阻塞狀態,那麼僅僅是執行緒的中斷標誌被修改為true而已;如果執行緒的當前狀態處於阻塞狀態,那麼在將中斷標誌設定為true後,還會有如下三種情況之一的操作:

  • 如果是wait、sleep以及jion三個方法引起的阻塞,那麼會將執行緒的中斷標誌重新設定為false,並丟擲一個InterruptedException;
  • 如果是java.nio.channels.InterruptibleChannel進行的io操作引起的阻塞,則會對執行緒丟擲一個ClosedByInterruptedException;(待驗證)
  • 如果是輪詢(java.nio.channels.Selectors)引起的執行緒阻塞,則立即返回,不會丟擲異常。(待驗證)
    如果在中斷時,執行緒正處於非阻塞狀態,則將中斷標誌修改為true,而在此基礎上,一旦進入阻塞狀態,則按照阻塞狀態的情況來進行處理;例如,一個執行緒在執行狀態中,其中斷標誌被設定為true,則此後,一旦執行緒呼叫了wait、jion、sleep方法中的一種,立馬丟擲一個InterruptedException,且中斷標誌被清除,重新設定為false。 通過上面的分析,我們可以總結,呼叫執行緒類的interrupted方法,其本質只是設定該執行緒的中斷標誌,將中斷標誌設定為true,並根據執行緒狀態決定是否丟擲異常。因此,通過interrupted方法真正實現執行緒的中斷原理是:開發人員根據中斷標誌的具體值,來決定如何退出執行緒。
   一個簡單的實現方式如下:
public void run() {
            try {
                while (true){
                    Thread.sleep(1000l);//阻塞狀態,執行緒被呼叫了interrupte()方法,清除中斷標誌,丟擲InterruptedException
                    //dosomething
                    boolean isIn = this.isInterrupted();
                    //執行狀態,執行緒被呼叫了interrupte()方法,中斷標誌被設定為true
                    //非阻塞狀態中進行中斷執行緒操作
                    if(isInterrupted()) break;//退出迴圈,中斷程序
                }
            }catch (InterruptedException e){//阻塞狀態中進行中斷執行緒操作
                boolean isIn = this.isInterrupted();//退出阻塞狀態,且中斷標誌被清除,重新設定為false,所以此處的isIn為false
                return;//退出run方法,中斷程序
            }
        }
        分別考慮了阻塞狀態中進行中斷執行緒和非阻塞狀態中中斷執行緒的處理方式。

        最後,說明一下interrupte方法的呼叫,該方法可在需要中斷的執行緒本身中呼叫,也可在其他執行緒中呼叫需要中斷的執行緒物件的該方法。