java中斷機(jī)制實(shí)例講解
一、導(dǎo)言
線程A對(duì)線程B發(fā)出建議: 你好,可以停止了喲~
在實(shí)際生產(chǎn)環(huán)境中,對(duì)于阻塞任務(wù),可能存在一些情況導(dǎo)致阻塞任務(wù)取消、終止,例如: 計(jì)時(shí)器到期,I/O 完成,或者另一個(gè)線程的動(dòng)作(釋放一個(gè)鎖,設(shè)置一個(gè)標(biāo)志,或者將一個(gè)任務(wù)放在一個(gè)工作隊(duì)列中)。這種情況下可以使用java的中斷機(jī)制來(lái)進(jìn)行線程間通信。
java線程中斷的實(shí)現(xiàn)是基于一個(gè)稱為中斷狀態(tài)的內(nèi)部標(biāo)志位來(lái)實(shí)現(xiàn)的,其中斷的含義更像是建議,一個(gè)線程如何響應(yīng)另一個(gè)線程的中斷完全取決于程序員: 繼續(xù)向上拋出、封裝后拋出、中斷狀態(tài)復(fù)原、忽略等。java庫(kù)中的許多拋出 InterruptedException 的方法(例如 sleep)都被設(shè)計(jì)為取消當(dāng)前操作并在接收到中斷時(shí)立即返回。
InterruptException異常就像是一個(gè)聲明,聲明拋出該異常的方法都可被中斷,比如wait、sleep、join。異常都是由可中斷方法自己拋出來(lái)的,并不是直接由interrupt()方法直接引起的。一般來(lái)說(shuō),任何通過(guò)拋出一個(gè) InterruptedException 來(lái)退出的方法都應(yīng)該清除中斷狀態(tài)。
二、java 中斷api
interrupt()
interrupt()方法本質(zhì)上就是通過(guò)調(diào)用java.lang.Thread#interrupt0設(shè)置中斷flag為true,如下代碼演示了該方法的使用: 另啟一個(gè)線程中斷了當(dāng)前線程。
@Test public void interruptSt() { Thread mainThread = Thread.currentThread(); new Thread(/*將當(dāng)前線程中斷*/mainThread::interrupt).start(); try { //public static native void sleep(long millis) throws InterruptedException; Thread.sleep(1_000); } catch (InterruptedException e) { System.out.println("main 線程被中斷了"); } /* * 輸出: main 線程被中斷了 */ }
interrupted()和isInterrupted()
public boolean isInterrupted() { // 設(shè)置this線程的中斷flag,不會(huì)重置中斷flag為true return isInterrupted(false); } public /*靜態(tài)方法*/static boolean interrupted() { // 設(shè)置當(dāng)前線程的中斷flag,重置中斷flag為true return currentThread().isInterrupted(true); }
使用示例
@Test public void test_Flag() { Thread currentThread = Thread.currentThread(); currentThread.interrupt(); System.out.println("當(dāng)前線程狀態(tài) =" + currentThread.isInterrupted()); System.out.println("當(dāng)前線程狀態(tài) =" + Thread.interrupted()); System.out.println("當(dāng)前線程狀態(tài) =" + Thread.interrupted()); /* 輸出 當(dāng)前線程狀態(tài) =true 當(dāng)前線程狀態(tài) =true 當(dāng)前線程狀態(tài) =false*/ }
三、如何響應(yīng)中斷?
調(diào)用一個(gè)可中斷的阻塞方法時(shí)需要處理受檢異常InterruptException,一般來(lái)說(shuō)最容易的方式就是繼續(xù)拋出InterruptException ,讓調(diào)用方?jīng)Q定對(duì)中斷事件作出什么應(yīng)對(duì)。但是對(duì)于一些不能在方法頭直接添加異常聲明的,可以catch出后再進(jìn)行一些操作,例如使用Runnable時(shí):
一般來(lái)說(shuō)當(dāng)catch到中斷時(shí),應(yīng)該對(duì)中斷狀態(tài)進(jìn)行還原: 調(diào)用Thread.currentThread().interrupt()
;,除非明確自己的操作不會(huì)丟失線程中斷的證據(jù),從而剝奪了上層棧的代碼處理中斷的機(jī)會(huì)。
四、總結(jié)
對(duì)目標(biāo)線程調(diào)用interrupt()
方法可以請(qǐng)求中斷一個(gè)線程,目標(biāo)線程通過(guò)檢測(cè)isInterrupted()標(biāo)志獲取自身是否已中斷。如果目標(biāo)線程處于阻塞狀態(tài),該線程會(huì)捕獲到InterruptedException
。一般來(lái)說(shuō)不要catchInterruptException
后不做處理(“生吞中斷”)。
五、參考文章
https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
到此這篇關(guān)于java中斷機(jī)制實(shí)例講解的文章就介紹到這了,更多相關(guān)java中斷機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA 16位ID生成工具類含16位不重復(fù)的隨機(jī)數(shù)數(shù)字+大小寫
這篇文章主要介紹了JAVA 16位ID生成工具類含16位不重復(fù)的隨機(jī)數(shù)數(shù)字+大小寫,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02Java中常見(jiàn)延時(shí)隊(duì)列的實(shí)現(xiàn)方案小結(jié)(建議收藏)
延時(shí)隊(duì)列它要具有隊(duì)列的特性,再給它附加一個(gè)延遲消費(fèi)隊(duì)列消息的功能,也就是說(shuō)可以指定隊(duì)列中的消息在哪個(gè)時(shí)間點(diǎn)被消費(fèi),這篇文章主要介紹了Java中常見(jiàn)延時(shí)隊(duì)列的實(shí)現(xiàn)方案總結(jié),需要的朋友可以參考下2024-04-04跟我學(xué)Java Swing之游戲設(shè)計(jì)(2)
跟我學(xué)Java Swing之游戲設(shè)計(jì)(2)...2006-12-12IDEA配置java開發(fā)環(huán)境(maven、gradle、tomcat)
這篇文章主要介紹了IDEA配置java開發(fā)環(huán)境(maven、gradle、tomcat),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Spring中property-placeholder的使用與解析詳解
本篇文章主要介紹了Spring中property-placeholder的使用與解析詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05