java 線程 中斷(轉)

轉自:http://414149609.iteye.com/blog/1204591

 

一、沒有任何語言方面的需求一個被中斷的線程應該終止。中斷一個線程只是爲了引起該線程的注意,被中斷線程可以決定如何應對中斷。 

我一直都以爲調了thread.interrupt()後,線程就立刻停止(類似已被廢棄的stop函數),如果真的這樣,那會讓尚未處理完的數據和狀態處於不可知的情況,容易導致不可預計的問題。interrupt更像一個通知,將Thead裏的中斷標誌位設爲true,而線程能否退出,就看用戶的代碼對於這個通知是怎麼處理的了。 

二、對於處於sleep,join等操作的線程,如果被調用interrupt()後,會拋出InterruptedException,然後線程的中斷標誌位會由true重置爲false,因爲線程爲了處理異常已經重新處於就緒狀態。 

我在運行thinking in java裏中斷的例子時,一直都很奇怪爲什麼在catch(InterruptedException e)的處理段裏,thead.isInterrupted()返回的都是false,原來是已被重置。 

三、循環任務線程的中斷 

1、任務類裏做一個信號變量boolean isStopped。循環每次都檢查信號量,如果外部邏輯將isStopped設爲true,則線程退出。 

2、利用線程類已有的信號量isInterrupted。由於sleep、join、wait等操作會拋出中斷異常,然後中斷標誌會被緊接着重置,所以需要做好異常處理。有兩種推薦的編碼結構: 

1.public void run() {    
2.    try {    
3.        ...    
4.        /*   
5.         * 不管循環裏是否調用過線程阻塞的方法如sleep、join、wait,這裏還是需要加上   
6.         * !Thread.currentThread().isInterrupted()條件,雖然拋出異常後退出了循環,顯   
7.         * 得用阻塞的情況下是多餘的,但如果調用了阻塞方法但沒有阻塞時,這樣會更安全、更及時。   
8.         */   
9.        while (!Thread.currentThread().isInterrupted()&& more work to do) {    
10.            do more work     
11.        }    
12.    } catch (InterruptedException e) {    
13.        //線程在wait或sleep期間被中斷了    
14.    } finally {    
15.        //線程結束前做一些清理工作    
16.    }    
17.} 


1.public void run() {    
2.    while (!Thread.currentThread().isInterrupted()&& more work to do) {    
3.        try {    
4.            ...    
5.            sleep(delay);    
6.        } catch (InterruptedException e) {    
7.            Thread.currentThread().interrupt();//重新設置中斷標示    
8.        }    
9.    }    
10.}  
四、不可中斷的操作,包括進入synchronized段以及Lock.lock(),inputSteam.read()等,調用interrupt()對於這幾個問題無效,因爲它們都不拋出中斷異常。如果拿不到資源,它們會無限期阻塞下去。 

對於Lock.lock(),可以改用Lock.lockInterruptibly(),可被中斷的加鎖操作,它可以拋出中斷異常。等同於等待時間無限長的Lock.tryLock(long time, TimeUnit unit)。 

對於inputStream等資源,有些(實現了interruptibleChannel接口)可以通過close()方法將資源關閉,對應的阻塞也會被放開。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章