<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Thread interrupt() 線程中斷的詳細說明

          共 8470字,需瀏覽 17分鐘

           ·

          2020-12-13 00:50

          點擊上方藍色字體,選擇“標星公眾號”

          優(yōu)質(zhì)文章,第一時間送達

          ? 作者?|??Arnold-zhao

          來源 |? urlify.cn/vuyaIv

          66套java從入門到精通實戰(zhàn)課程分享

          一個線程不應(yīng)該由其他線程來強制中斷或停止,而是應(yīng)該由線程自己自行停止。所以,Thread.stop, Thread.suspend, Thread.resume 都已經(jīng)被廢棄了。Java Thread.interrupt()方法所提供的線程中斷,實際就是從線程外界,修改線程內(nèi)部的一個標志變量,或者讓線程中的一些阻塞方法,拋出InterruptedException。以此”通知“線程去做一些事情, 至于做什么,做不做,實際完全是由線程內(nèi)的業(yè)務(wù)代碼自己決定的。不過一般都是釋放資源并結(jié)束線程。

          基本概念

          public?static?void?basic()?{

          ????????Thread?testThread?=?new?Thread(new?Runnable()?{
          ????????????@Override
          ????????????public?void?run()?{
          ????????????????System.out.println();
          ????????????}
          ????????});

          ????????testThread.interrupt();?????????//是給線程設(shè)置中斷標志;??其作用是中斷此線程(此線程不一定是當前線程,而是指調(diào)用該方法的Thread實例所代表的線程)

          ??????? testThread.isInterrupted();?????//只檢測中斷;??作用于此線程,即代碼中調(diào)用此方法的實例所代表的線程;作用是只測試此線程是否被中斷?,不清除中斷狀態(tài)。
          ??????? testThread.interrupted();???????//是檢測中斷并清除中斷狀態(tài);?作用于當前線程(作用是測試當前線程是否被中斷(檢查中斷標志),返回一個boolean并清除中斷狀態(tài),第二次再調(diào)用時中斷狀態(tài)已經(jīng)被清除,將返回一個false)
          ????????Thread.interrupted();???????????//同上


          ????????//************************************

          ????????testThread.interrupt();?//設(shè)置指定testThread線程的狀態(tài)為中斷標志,

          ??????? testThread.isInterrupted();//?檢測當前testThread線程是否被外界中斷;是則返回true
          ????????testThread.interrupted();//檢測當前testThread線程是否收到中斷信令,收到信令則返回true且清除中斷狀態(tài),重新變更為false;
          ????????Thread.interrupted();//靜態(tài)方法,與testThread.interrupted()一樣,(檢測當前testThread線程是否被中斷,如果被中斷則返回true且清除中斷狀態(tài),重新變更為未中斷狀態(tài);)?作用于當前被執(zhí)行線程,由于testThread內(nèi)部線程在執(zhí)行的時候,是無法獲取testThread引用的,所以如果想檢測當前自己的線程是否被中斷且清除中斷狀態(tài),則可以使用Thread.interrupted()方法;


          ????????//如上,其實關(guān)于線程中斷一共也就上述三個方法,其中interrupt()和isInterrupted()?是線程實例方法,interrupted()則是線程的靜態(tài)方法;
          ????????//isInterrupted()是線程實例方法,所以,線程內(nèi)部執(zhí)行代碼中是無法獲取testThread的引用的所以無法執(zhí)行實例方法isInterrupted();
          ????????//但其實,我們可以通過在線程內(nèi)部執(zhí)行代碼中使用 Thread.currentThread()獲取當前線程的實例,此時使用Thread.currentThread().isInterrupted()?的方式來調(diào)用isInterrupted()方法;等價于testThread.isInterrupted();
          ????????//等價與:線程外部做檢測用:testThread.isInterrupted();?線程內(nèi)部做檢測用:Thread.currentThread().isInterrupted()

          ????}

          線程中斷驗證

          /**
          ?????*?驗證一般情況下使用interrupt()?中斷執(zhí)行線程的例子
          ?????*/
          ????public?static?void?threadStopTest()?{
          ????????Thread?testThread?=?new?Thread(new?Runnable()?{
          ????????????@Override
          ????????????public?void?run()?{
          ????????????????//第一種情況:檢測線程是否收到中斷信令,收到則返回true,并清除當前的線程狀態(tài),重新變更為未中斷;
          ??????????????/*??while?(!Thread.interrupted())?{
          ????????????????????System.out.println("線程內(nèi)代碼執(zhí)行");
          ????????????????}
          ????????????????//此時再檢測當前該線程是否收到外界中斷信令,得到結(jié)果為false,因為使用Thread.interrupted(),在收到中斷信令后,會清除當前的線程狀態(tài),所以此處進行判斷時則返回結(jié)果為false,線程狀態(tài)未收到中斷信令
          ????????????????System.out.println(Thread.currentThread().isInterrupted());
          ????????????????System.out.println(Thread.currentThread().isInterrupted());
          */
          ????????????????//第二種情況:檢測線程是否收到中斷信令,收到則返回true,只是檢測當前是否收到中斷信令,不清除當前的線程狀態(tài),
          ????????????????while?(!Thread.currentThread().isInterrupted())?{
          ????????????????????System.out.println("線程內(nèi)代碼執(zhí)行");
          ????????????????}
          ????????????????//此時檢測當前該線程是否收到外界中斷信令,true表示收到,此處獲取結(jié)果為?true
          ????????????????System.out.println(Thread.currentThread().isInterrupted());?//true
          ????????????????System.out.println(Thread.currentThread().isInterrupted());?//true
          ????????????????//線程被中斷后執(zhí)行該代碼塊,進行回收工作
          ????????????????System.out.println("線程收到外部中斷通知,已進行線程內(nèi)部回收,中斷完成");
          ????????????????/*while?(true)?{

          ????????????????}*/
          ????????????}
          ????????});
          ????????testThread.start();
          ????????try?{
          ????????????Thread.sleep(5000);
          ????????????//等待5秒后?發(fā)出中斷信號,通知testThread線程進行中斷
          ????????????testThread.interrupt();
          ????????????//判斷當前該線程是否中斷完成
          ????????????boolean?flag?=?true;
          ????????????int?index?=?0;
          ????????????Thread.sleep(1000);
          ????????????while?(flag)?{
          ????????????????//獲取指定線程是否收到中斷信號,返回true表示線程已經(jīng)收到中斷信號,但線程正在運行,處理中;或者是已經(jīng)收到了中斷信令,但是選擇了不中斷繼續(xù)執(zhí)行;
          ????????????????//?如果返回false則存在兩種情況
          ????????????????//1、是當前該線程已經(jīng)執(zhí)行完畢,完成中斷;由于此時線程已經(jīng)執(zhí)行完成了,那么此處再獲取該線程的信令時則返回為false
          ????????????????//2、該線程沒有完成中斷,但是該線程代碼內(nèi)部使用了Thread.interrupted()?清除了線程的信令狀態(tài),此時則也是返回結(jié)果為false,
          ????????????????System.out.println("檢測線程的中斷信號:"?+?testThread.isInterrupted());
          ????????????????//循環(huán)檢測10秒鐘,10秒后則跳出循環(huán)
          ????????????????Thread.sleep(1000);
          ????????????????index++;
          ????????????????if?(index?==?10)?{
          ????????????????????//停止檢測
          ????????????????????flag?=?false;
          ????????????????}
          ????????????}
          ????????????if?(!testThread.isInterrupted())?{
          ????????????????//TODO:?testThread線程中斷完成,則執(zhí)行該代碼塊
          ????????????????System.out.println("外部檢測testThread中斷完成");
          ????????????}?else?{
          ????????????????//TODO:?否則,則執(zhí)行另外代碼塊
          ????????????????System.out.println("外部檢測testThread中斷失敗");
          ????????????}

          ????????}?catch?(InterruptedException?e)?{
          ????????????e.printStackTrace();
          ????????}
          ????}

          驗證線程中斷,拋出InterruptedException異常的情況

          /**
          ?????*?驗證線程中斷,拋出InterruptedException異常的情況;
          ?????*/
          ????public?static?void?threadStopTest2()?{

          ????????/**
          ?????????*?當外部調(diào)用對應(yīng)線程進行中斷的信令時,如果此時該執(zhí)行線程處于被阻塞狀態(tài),如;Thread.sleep(),Object.wait(),BlockingQueue#put、BlockingQueue#take?等
          ?????????*?那么此時通過調(diào)用當前線程對象的interrupt方法觸發(fā)這些函數(shù)拋出InterruptedException異常。
          ?????????*?當一個函數(shù)拋出InterruptedException異常時,表示這個方法阻塞的時間太久了,外部應(yīng)用不想等它執(zhí)行結(jié)束了。
          ?????????*?當你的捕獲到一個InterruptedException異常后,亦可以處理它,或者向上拋出。
          ?????????*
          ?????????*?拋出時要注意???:當你捕獲到InterruptedException異常后,當前線程的中斷狀態(tài)已經(jīng)被修改為false;
          ?????????*?此時你若能夠處理中斷,正常結(jié)束線程,則不用理會該值;但如果你繼續(xù)向上拋InterruptedException異常,你需要再次調(diào)用interrupt方法,將當前線程的中斷狀態(tài)設(shè)為true。
          ?????????*
          ?????????*/

          ????????Thread?testThread?=?new?Thread(new?Runnable()?{
          ????????????@Override
          ????????????public?void?run()?{
          ????????????????try?{
          ????????????????????//外部調(diào)用信令,要中斷該線程時,如果此時線程正在休眠或者阻塞中,則將會拋出異常
          ????????????????????Thread.sleep(6000);
          ????????????????}?catch?(InterruptedException?e)?{
          ????????????????????//第一種情況:進入異常捕獲,此處捕獲到異常,則說明當前該線程被外界要求進行中斷,此時我們可以選擇中斷該線程;那么此時后續(xù)的while循環(huán)則將不會被執(zhí)行,線程執(zhí)行完畢,則結(jié)束;

          ????????????????????/*if?(1?>?0)?{
          ????????????????????????return;
          ????????????????????}
          ????????????????????*/

          ????????????????????//第二種情況:當然,我們也可以選擇收到中斷信令后,不進行線程中斷;比如,當前的線程的確處于正常的阻塞期間,阻塞完成后,我還是要執(zhí)行while循環(huán)的,等到最終while循環(huán)執(zhí)行完畢后,才正常的結(jié)束線程的生命周期;
          ????????????????????//那么此時,捕獲到異常后不做任何操作即可;需要注意的是,此時捕獲了InterruptedException異常后,此時的線程狀態(tài)將會自動被修改為false
          ????????????????????//?(false表示線程沒有收到過中斷信令,或者是線程已經(jīng)中斷完成,或者是線程使用了Thread.interrupted()清除了信令狀態(tài))沒有收到過中斷信令這個基本是不可能的,只要外部有進行調(diào)用,則百分百收到信令,除非是在調(diào)用中斷信令前,獲取了一下線程的狀態(tài),此時則肯定是false的;如:先執(zhí)行,testThread.isInterrupted(),再執(zhí)行testThread.interrupt();則此時第一個執(zhí)行的isInterrupted()肯定是false,這個場景意義不大;
          ????????????????????//1、對于外界來說,收到線程的信令狀態(tài)是false,則表示該線程已經(jīng)是執(zhí)行完成了;當然存在線程信令為false是內(nèi)部線程自己進行了轉(zhuǎn)換,但實際上并沒有停止線程執(zhí)行的情況;
          ????????????????????//所以一般情況下,按照約定來說,如果內(nèi)部線程收到中斷請求后,此時如果需要繼續(xù)執(zhí)行,不理會外部的中斷信令,那么此時可以執(zhí)行:Thread.currentThread().interrupt();重新將內(nèi)部狀態(tài)轉(zhuǎn)換為true
          ????????????????????//這樣,外部線程在重新檢測當前線程的信令狀態(tài)時為true時,則知道,內(nèi)部線程已經(jīng)收到了中斷信令,而不是一直沒有收到中斷信令。

          ????????????????????//此處為false,捕獲該中斷異常后,將會自動修改線程狀態(tài)為false
          ????????????????????System.out.println("異常"?+?Thread.currentThread().isInterrupted());
          ????????????????????//此處由于要繼續(xù)執(zhí)行該線程,不執(zhí)行線程中斷,所以重新修改中斷狀態(tài)為true
          ????????????????????Thread.currentThread().interrupt();
          ????????????????????//此時獲取結(jié)果為true;
          ????????????????????System.out.println("異常"?+?Thread.currentThread().isInterrupted());
          ????????????????}
          ????????????????while?(true)?{
          ????????????????????System.out.println("線程內(nèi)部執(zhí)行中");
          ????????????????}

          ????????????}
          ????????});
          ????????testThread.start();

          ????????//發(fā)出線程中斷信令
          ????????testThread.interrupt();
          ????}

          約定

          /**
          ?????*?約定:
          ?????*?內(nèi)部中斷的線程,如果需要繼續(xù)執(zhí)行,則必須重新設(shè)置信令狀態(tài)為true;此時外部調(diào)用者才會清楚當前線程已經(jīng)收到中斷信令但是還要繼續(xù)執(zhí)行;
          ?????*?


          ?????*?什么情況下,線程狀態(tài)會自動變更為false?
          ?????*?


          ?????*?1、線程自動執(zhí)行完畢后,則狀態(tài)將會自動置為?false;
          ?????* 2、線程內(nèi)部使用:Thread.interrupted()方法獲取線程狀態(tài)時,將會自動清除線程狀態(tài),使當前線程狀態(tài)重新更改為false;
          ?????*?3、線程內(nèi)部如果捕獲了,InterruptedException異常,那么此時線程狀態(tài)也會自動修改為false
          ?????*?


          ?????*?所以,
          ?????* 1、如果是使用Thread.interrupted()來獲取線程狀態(tài)的情況,使用完以后,必須保證線程是正常中斷的;如果不能保證,建議使用Thread.currentThread().isInterrupted()來獲取線程狀態(tài);isInterrupted()方法只獲取線程狀態(tài),不會更改線程狀態(tài);
          ?????* 2、對于線程內(nèi)使用try catch 捕獲了InterruptedException異常的情況,則捕獲完以后,一定要做相關(guān)操作,而不要只捕獲異常,但是不處理該中斷信令;
          ?????*?當前捕獲到異常后,如果需要中斷,則直接中斷線程即可
          ?????*?當前捕獲到異常后,如果不需要中斷,需要繼續(xù)執(zhí)行線程,則此時需要執(zhí)行Thread.currentThread().interrupt();重新更改下自己的線程狀態(tài)為true,表示當前線程需要繼續(xù)執(zhí)行;
          ?????*?當前捕獲到異常后,如果不需要中斷,而是將異常外拋給上層方法進行處理,那么此時也需要執(zhí)行Thread.currentThread().interrupt();重新更改下自己的線程狀態(tài)為true,表示當前線程需要繼續(xù)執(zhí)行;
          ?????*/

          public?static?void?main(String[]?args)?throws?InterruptedException?{
          //????????threadStopTest();


          ????????/*
          ????????Thread.currentThread().interrupt();
          ????????System.out.println(Thread.currentThread().isInterrupted());true
          ????????System.out.println(Thread.currentThread().isInterrupted());true
          ????????System.out.println(Thread.currentThread().isInterrupted());true
          ????????System.out.println(Thread.interrupted());true
          ????????System.out.println(Thread.currentThread().isInterrupted());false
          ????????System.out.println(Thread.interrupted());false
          ????????*/





          粉絲福利:Java從入門到入土學(xué)習(xí)路線圖

          ???

          ?長按上方微信二維碼?2 秒


          感謝點贊支持下哈?

          瀏覽 50
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人精品午夜无码免费 | 贵族学校极品粉穴清纯学生妹 | 午夜操操 | 亚洲殴洲国产黄片 | 国产无遮挡又黄又爽免费网站 |