中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java線程Thread之interrupt中斷的示例分析

發布時間:2021-09-09 10:27:28 來源:億速云 閱讀:150 作者:小新 欄目:編程語言

這篇文章將為大家詳細講解有關Java線程Thread之interrupt中斷的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

中斷線程

線程的thread.interrupt()方法是中斷線程,將會設置該線程的中斷狀態位,即設置為true,中斷的結果線程是死亡、還是等待新的任務或是繼續運行至下一步,就取決于這個程序本身。線程會不時地檢測這個中斷標示位,以判斷線程是否應該被中斷(中斷標示值是否為true)。它并不像stop方法那樣會中斷一個正在運行的線程。

判斷線程是否被中斷

判斷某個線程是否已被發送過中斷請求,請使用Thread.currentThread().isInterrupted()方法(因為它將線程中斷標示位設置為true后,不會立刻清除中斷標示位,即不會將中斷標設置為false),而不要使用thread.interrupted()(該方法調用后會將中斷標示位清除,即重新設置為false)方法來判斷,下面是線程在循環中時的中斷方式:

while(!Thread.currentThread().isInterrupted() && more work to do){
 do more work
}

interrupt之中斷狀態標記

interrupt中斷機制中有如下方法:

  1. Thread.interrupt(),設置當前中斷標記為true(類似屬性的set方法)

  2. Thread.isInterrupted(),檢測當前的中斷標記(類似屬性的get方法)

  3. Thread.interrupted(),檢測當前的中斷標記,然后重置中斷標記為false(類似屬性的get方法+set方法)

因此interrupt中斷機制并不是真正的將當前線程中斷,而是一個中斷標記的變化。我們先用例子來測試一下。

public class InterruptTest {
 //這里用來打印消耗的時間
 private static long time = 0;
 private static void resetTime(){
 time = System.currentTimeMillis();
 }
 private static void printContent(String content){
 System.out.println(content + "  時間:" + (System.currentTimeMillis() - time));
 }

 public static void main(String[] args) {
 test1();
 }

 private static void test1(){
 Thread1 thread1 = new Thread1();
 thread1.start();
 //延時3秒后interrupt中斷
 try {
  Thread.sleep(3000);
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 thread1.interrupt();
 printContent("執行中斷");
 }

 private static class Thread1 extends Thread{
 @Override public void run() {
  resetTime();
  int num = 0;
  while (true){
  if(isInterrupted()){
   printContent("當前線程 isInterrupted");
   break;
  }
  num++;
  if(num % 100 == 0){
   printContent("num : " + num);
  }
  }
 }
 }
}

以上代碼是開啟一個Thread1線程,在Thread1線程的while循環中不斷對num加1,每到100的倍數打印一次(防止打印太快)。然后主線程在sleep了3000毫秒后,調用Thread1線程的interrupt方法。那么我們看看輸出結果:

Java線程Thread之interrupt中斷的示例分析

intterupt中斷

可以看到,在耗時3000毫秒左右,也就是主線程sleep之后執行thread1.interrupt();后,Thread1線程停止了,而Thread1線程的停止是因為while循環中的isInterrupted方法返回了true,所以break退出了while循環,也就是說interrupt和isInterrupted在這里起到的作用就相當于setXX和getXX的作用,維護著一個boolean變量。

interrupt之中斷異常處理

當然interrupt機制并不僅僅是一個中斷狀態位的變化和檢測,它還可以進行中斷異常的處理。我們知道Thread.sleep()方法需要捕獲中斷異常,那接下來我們往其中添加一個sleep延時試試

 while (true){
 if(isInterrupted()){
  printContent("當前線程 isInterrupted");
  break;
 }
 num++; 
 //sleep一下
 try {
  Thread.sleep(1);
 } catch (InterruptedException e) {
  e.printStackTrace();
 }

 if(num % 100 == 0){
  printContent("num : " + num);
 }
 }

我們再看看輸出結果:

Java線程Thread之interrupt中斷的示例分析

intterupt中斷

這里我們會發現,sleep睡眠之后,輸出的num值明顯小了好多(沒睡眠時num都達到10億的大小了,看來CPU執行簡單運算還是非常快的),哈哈,不過這不是重點,重點是是看到輸出了一個異常,還有就是輸出異常后,isInterrupted輸出返回false,Thread1線程又繼續執行下去了,并沒有退出while循環。那么這是為什么呢?我們只是加了一個sleep睡眠而已。

如果Thread1線程中有執行需要捕獲InterruptedException異常的操作,比如Thread的sleep,join方法,Object的wait,Condition的await等,它是強制需要捕獲InterruptedException異常的,那么當thread1.interrupt方法調用之后,它會給thread1線程拋出一個InterruptedException異常,那么在while循環中,就能捕獲到這個異常然后這個異常拋出之后,又會馬上將線程中斷標識重置為false,因此在下次的while循環中判斷isInterrupted時,它是false,也就不會break,然后while循環會一直執行下去。

因此interrupt()方法會根據thread線程中的run方法里是否有必須捕獲InterruptedException異常的代碼,而做出不同操作:

  1. 如果沒有必須捕獲InterruptedException異常的代碼(比如Thread.sleep()),則isInterrupted()會返回true,此時可以在isInterrupted的判斷中處理中斷變化。

  2. 如果有必須捕獲InterruptedException異常的代碼(比如Thread.sleep()),則會拋出InterruptedException異常,并進行捕獲,同時重置isInterrupted為false,此時得在異常捕獲中處理中斷變化。

interrupt的應用場景

通常interrupt適用于在線程執行中的循環標記判斷,例如

while(!isInterrupted()){
 ...
}

但是如果在本次循環中出現阻塞了,那么線程就無法判斷下次的isInterrupted標記,那么即便調用了interrupt()方法也無法退出循環,也就無法退出線程。例如

while(!isInterrupted()){
 ... 
 while(true){
  //線程卡在這里了,則無法響應interrupte機制了
 }
}

這樣的話,interrupt就沒轍了,線程會一直執行下去,不會被中斷停止。

關于“Java線程Thread之interrupt中斷的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巴林右旗| 利辛县| 柯坪县| 高雄县| 白玉县| 云南省| 来宾市| 张家港市| 锡林郭勒盟| 密山市| 蓝田县| 丹阳市| 肃南| 汝州市| 都兰县| 鄂尔多斯市| 武安市| 富锦市| 甘泉县| 迁安市| 克山县| 桂东县| 板桥市| 博湖县| 蕉岭县| 平和县| 金溪县| 敖汉旗| 竹北市| 竹山县| 泰州市| 互助| 克东县| 大英县| 太仆寺旗| 江孜县| 金湖县| 梁河县| 丹东市| 威远县| 伊宁市|