最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Java線程Thread之interrupt中斷解析

 更新時(shí)間:2018年01月29日 11:02:20   作者:Ihesong  
這篇文章主要介紹了Java線程Thread之interrupt中斷解析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

這一篇我們說(shuō)說(shuō)Java線程Thread的interrupt中斷機(jī)制。

中斷線程

線程的thread.interrupt()方法是中斷線程,將會(huì)設(shè)置該線程的中斷狀態(tài)位,即設(shè)置為true,中斷的結(jié)果線程是死亡、還是等待新的任務(wù)或是繼續(xù)運(yùn)行至下一步,就取決于這個(gè)程序本身。線程會(huì)不時(shí)地檢測(cè)這個(gè)中斷標(biāo)示位,以判斷線程是否應(yīng)該被中斷(中斷標(biāo)示值是否為true)。它并不像stop方法那樣會(huì)中斷一個(gè)正在運(yùn)行的線程。

判斷線程是否被中斷

判斷某個(gè)線程是否已被發(fā)送過(guò)中斷請(qǐng)求,請(qǐng)使用Thread.currentThread().isInterrupted()方法(因?yàn)樗鼘⒕€程中斷標(biāo)示位設(shè)置為true后,不會(huì)立刻清除中斷標(biāo)示位,即不會(huì)將中斷標(biāo)設(shè)置為false),而不要使用thread.interrupted()(該方法調(diào)用后會(huì)將中斷標(biāo)示位清除,即重新設(shè)置為false)方法來(lái)判斷,下面是線程在循環(huán)中時(shí)的中斷方式:

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

interrupt之中斷狀態(tài)標(biāo)記

interrupt中斷機(jī)制中有如下方法:

  1. Thread.interrupt(),設(shè)置當(dāng)前中斷標(biāo)記為true(類(lèi)似屬性的set方法)
  2. Thread.isInterrupted(),檢測(cè)當(dāng)前的中斷標(biāo)記(類(lèi)似屬性的get方法)
  3. Thread.interrupted(),檢測(cè)當(dāng)前的中斷標(biāo)記,然后重置中斷標(biāo)記為false(類(lèi)似屬性的get方法+set方法)

因此interrupt中斷機(jī)制并不是真正的將當(dāng)前線程中斷,而是一個(gè)中斷標(biāo)記的變化。我們先用例子來(lái)測(cè)試一下。

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

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

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

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

以上代碼是開(kāi)啟一個(gè)Thread1線程,在Thread1線程的while循環(huán)中不斷對(duì)num加1,每到100的倍數(shù)打印一次(防止打印太快)。然后主線程在sleep了3000毫秒后,調(diào)用Thread1線程的interrupt方法。那么我們看看輸出結(jié)果:

intterupt中斷

可以看到,在耗時(shí)3000毫秒左右,也就是主線程sleep之后執(zhí)行thread1.interrupt();后,Thread1線程停止了,而Thread1線程的停止是因?yàn)閣hile循環(huán)中的isInterrupted方法返回了true,所以break退出了while循環(huán),也就是說(shuō)interrupt和isInterrupted在這里起到的作用就相當(dāng)于setXX和getXX的作用,維護(hù)著一個(gè)boolean變量。

interrupt之中斷異常處理

當(dāng)然interrupt機(jī)制并不僅僅是一個(gè)中斷狀態(tài)位的變化和檢測(cè),它還可以進(jìn)行中斷異常的處理。我們知道Thread.sleep()方法需要捕獲中斷異常,那接下來(lái)我們往其中添加一個(gè)sleep延時(shí)試試

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

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

我們?cè)倏纯摧敵鼋Y(jié)果:

intterupt中斷

這里我們會(huì)發(fā)現(xiàn),sleep睡眠之后,輸出的num值明顯小了好多(沒(méi)睡眠時(shí)num都達(dá)到10億的大小了,看來(lái)CPU執(zhí)行簡(jiǎn)單運(yùn)算還是非??斓模?,哈哈,不過(guò)這不是重點(diǎn),重點(diǎn)是是看到輸出了一個(gè)異常,還有就是輸出異常后,isInterrupted輸出返回false,Thread1線程又繼續(xù)執(zhí)行下去了,并沒(méi)有退出while循環(huán)。那么這是為什么呢?我們只是加了一個(gè)sleep睡眠而已。

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

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

  1. 如果沒(méi)有必須捕獲InterruptedException異常的代碼(比如Thread.sleep()),則isInterrupted()會(huì)返回true,此時(shí)可以在isInterrupted的判斷中處理中斷變化。
  2. 如果有必須捕獲InterruptedException異常的代碼(比如Thread.sleep()),則會(huì)拋出InterruptedException異常,并進(jìn)行捕獲,同時(shí)重置isInterrupted為false,此時(shí)得在異常捕獲中處理中斷變化。

interrupt的應(yīng)用場(chǎng)景

通常interrupt適用于在線程執(zhí)行中的循環(huán)標(biāo)記判斷,例如

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

但是如果在本次循環(huán)中出現(xiàn)阻塞了,那么線程就無(wú)法判斷下次的isInterrupted標(biāo)記,那么即便調(diào)用了interrupt()方法也無(wú)法退出循環(huán),也就無(wú)法退出線程。例如

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

這樣的話,interrupt就沒(méi)轍了,線程會(huì)一直執(zhí)行下去,不會(huì)被中斷停止。

測(cè)試?yán)硬榭?我的GitHub--JavaTest

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • WebService教程詳解(一)

    WebService教程詳解(一)

    WebService,顧名思義就是基于Web的服務(wù)。它使用Web(HTTP)方式,接收和響應(yīng)外部系統(tǒng)的某種請(qǐng)求,接下來(lái)通過(guò)本文給大家介紹WebService教程詳解(一),對(duì)webservice教程感興趣的朋友一起學(xué)習(xí)吧
    2016-03-03
  • Spring-AOP @AspectJ切點(diǎn)函數(shù)之@annotation()用法

    Spring-AOP @AspectJ切點(diǎn)函數(shù)之@annotation()用法

    這篇文章主要介紹了Spring-AOP @AspectJ切點(diǎn)函數(shù)之@annotation()用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java利用Geotools從DEM數(shù)據(jù)中讀取指定位置的高程信息全過(guò)程

    Java利用Geotools從DEM數(shù)據(jù)中讀取指定位置的高程信息全過(guò)程

    Geotools作為一款功能強(qiáng)大且開(kāi)源的地理工具庫(kù),為地理數(shù)據(jù)的處理和分析提供了豐富的類(lèi)庫(kù)和便捷的接口,能夠很好地滿足從DEM數(shù)據(jù)中讀取高程信息這一實(shí)戰(zhàn)需求,本文將深入講解如何利用Geotools從獲取DEM數(shù)據(jù)到成功讀取指定位置高程信息的全過(guò)程,需要的朋友可以參考下
    2025-03-03
  • springboot添加AOP日志配置詳解

    springboot添加AOP日志配置詳解

    這篇文章主要介紹了springboot添加AOP日志配置詳解,日志是一種在軟件開(kāi)發(fā)中常用的技術(shù),用于記錄和跟蹤應(yīng)用程序的運(yùn)行過(guò)程,通過(guò)AOP日志,開(kāi)發(fā)人員可以實(shí)時(shí)監(jiān)控應(yīng)用程序的行為,包括方法的調(diào)用、參數(shù)的傳遞和返回值的獲取等,需要的朋友可以參考下
    2023-10-10
  • Spring引入外部屬性文件配置數(shù)據(jù)庫(kù)連接的步驟詳解

    Spring引入外部屬性文件配置數(shù)據(jù)庫(kù)連接的步驟詳解

    這篇文章主要介紹了Spring引入外部屬性文件配置數(shù)據(jù)庫(kù)連接的步驟詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Java異常的幾個(gè)謎題_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java異常的幾個(gè)謎題_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    本文給大家收藏整理java異常的幾個(gè)謎題,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-06-06
  • Java之URLEncoder、URLDecoder、Base64編碼與解碼方式

    Java之URLEncoder、URLDecoder、Base64編碼與解碼方式

    這篇文章主要介紹了Java之URLEncoder、URLDecoder、Base64編碼與解碼方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java遍歷Map對(duì)象集合的六種方式代碼示例

    Java遍歷Map對(duì)象集合的六種方式代碼示例

    Java中的Map是一種鍵值對(duì)映射的數(shù)據(jù)結(jié)構(gòu),它提供了一些常用的方法用于獲取、添加、刪除和修改元素,下面這篇文章主要給大家介紹了關(guān)于Java遍歷Map對(duì)象集合的六種方式,需要的朋友可以參考下
    2024-02-02
  • 第三方網(wǎng)站微信登錄java代碼實(shí)現(xiàn)

    第三方網(wǎng)站微信登錄java代碼實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了第三方網(wǎng)站微信登錄的java代碼實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • java實(shí)現(xiàn)基于UDP協(xié)議網(wǎng)絡(luò)Socket編程(C/S通信)

    java實(shí)現(xiàn)基于UDP協(xié)議網(wǎng)絡(luò)Socket編程(C/S通信)

    這篇文章主要介紹了java實(shí)現(xiàn)基于UDP協(xié)議網(wǎng)絡(luò)Socket編程(C/S通信),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10

最新評(píng)論

商城县| 苗栗市| 吴旗县| 深泽县| 柘城县| 松阳县| 新乐市| 乌兰察布市| 新津县| 大同县| 盐津县| 海安县| 高邮市| 西畴县| 江达县| 屯留县| 青州市| 赣榆县| 大方县| 衡东县| 伊通| 同心县| 阆中市| 福鼎市| 丰原市| 韩城市| 贵德县| 阿坝| 昆山市| 连山| 桦甸市| 苏尼特右旗| 交口县| 江城| 阜新| 什邡市| 平武县| 阿瓦提县| 淮北市| 峨边| 兴安县|