- Java 9 并發編程實戰
- (西班牙)哈維爾·費爾南德茲·岡薩雷斯
- 1080字
- 2020-01-16 14:07:49
1.3 線程中斷
一個多線程Java程序,只有當其全部線程執行結束時(更具體地說,是所有非守護線程結束或者某個線程調用System.exit()方法的時候),才會結束運行。有時,為了終止程序或者取消一個線程對象所執行的任務,我們需要終止一個線程。
Java使用一種中斷機制來向線程表明想要終止它。這個中斷機制依靠線程對象來檢查是否需要中斷,同時線程對象可以決定是否響應中斷請求。當然,一個線程對象也可以忽略中斷請求繼續執行。
本節將開發一個應用程序,它的作用是在線程創建5s后,使用中斷機制強制結束線程。
項目準備
本案例是用Eclipse IDE來實現的。如果開發者使用Eclipse或者其他IDE(例如NetBeans),則應打開它并創建一個新的Java項目。
案例實現
根據以下步驟來完成本案例。
1.創建一個名為PrimeGenerator的類,并繼承Thread類:
public class PrimeGenerator extends Thread{
2.重寫run()方法——該方法包含一個無限while循環。在循環中,處理從1開始的連續數字。如果是奇數,那么將其輸出到控制臺:
@Override public void run() { long number=1L; while (true) { if (isPrime(number)) { System.out.printf("Number %d is Prime\n",number); }
3.每處理完一個數字,通過isInterrupted()方法來判斷當前線程是否已被中斷。如果該方法返回true,那么表明當前線程已被中斷。在這種情況下,在控制臺上打印一條信息并終止線程:
if (isInterrupted()) { System.out.printf("The Prime Generator has been Interrupted"); return; } number++; } }
4.實現isPrime()方法。詳細代碼參見1.2節。
5.現在,開始實現應用程序的主類,創建包含main()方法的Main類:
public class Main { public static void main(String[] args) {
6.創建PrimeGenerator類的對象,并啟動它:
Thread task=new PrimeGenerator(); task.start();
7.在主線程中等待5s后,中斷PrimeGenerator線程:
try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } task.interrupt();
8.輸出中斷線程的狀態。這段代碼的輸出結果取決于它是在線程結束前還是線程結束后運行的:
System.out.printf("Main: Status of the Thread: %s\n",task.getState()); System.out.printf("Main: isInterrupted: %s\n",task.isInterrupted()); System.out.printf("Main: isAlive: %s\n", task.isAlive()); }
9.運行案例并查看結果。
結果分析
下面是以上案例運行結果的截圖。從圖中可以看到,PrimeGenerator線程在檢測到自己被中斷后,輸出信息并結束了運行。

Thread類有一個用來保存線程是否已被中斷的狀態屬性,其屬性值為boolean類型,默認值為false。當調用一個線程對象的interrupt()方法時,該狀態屬性將修改為true。而方法isInterrupted()僅返回該狀態屬性的值。
在main()方法中,輸出了中斷線程的一些狀態信息。在本案例中,雖然在這些代碼之前調用了線程的中斷,但是在執行這些代碼時,任務線程并未執行到中斷判斷和處理過程,因此,此時輸出的線程狀態為RUNNABLE,方法isInterrupted()的結果為true,當然方法isAlive()的結果也為true。如果這些代碼執行是在Thread中斷完成之后[可以制造機會,如通過在main調用sleep()使得主線程休眠1s,使得task線程完成中斷,那么isInterrupted()和isAlive()的結果將為false。
其他說明
在Thread類中,還有一個靜態方法interrupted(),也能用來檢測當前線程是否已被中斷。
注意:
isInterrupted()方法和interrupted()方法之間有一個重要的不同點:isInterrupted()方法不會修改線程的是否中斷屬性,而interrupted()方法會將中斷屬性設置為false。
正如前文所說,線程對象可以忽略中斷,但這并不是被預期的行為。
- Node.js Design Patterns
- 數據庫系統教程(第2版)
- C語言程序設計案例教程(第2版)
- SOA實踐
- Delphi程序設計基礎:教程、實驗、習題
- Java EE框架整合開發入門到實戰:Spring+Spring MVC+MyBatis(微課版)
- iOS開發實戰:從零基礎到App Store上架
- Mastering C# Concurrency
- Spring核心技術和案例實戰
- 利用Python進行數據分析
- 從Excel到Python數據分析:Pandas、xlwings、openpyxl、Matplotlib的交互與應用
- Android 游戲開發大全(第二版)
- Test-Driven iOS Development with Swift
- 和孩子一起學編程:用Scratch玩Minecraft我的世界
- Python數據預處理技術與實踐