轉自: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()方法將資源關閉,對應的阻塞也會被放開。