java中線程中斷的實(shí)現(xiàn)示例
1、線程中斷 即 線程的取消/關(guān)閉的機(jī)制
Java中停止一個(gè)線程的主要機(jī)制是中斷,中斷并不是強(qiáng)迫終止一個(gè)線程,它是一種 協(xié)作機(jī)制 ,是給線程傳遞一個(gè)取消/關(guān)閉信號(hào),由線程自身來(lái)決定如何以及何時(shí)退出。
停止線程,但這個(gè)方法被標(biāo)記為了過(guò)時(shí)。 @Deprecated public final void stop() ========================= 返回對(duì)應(yīng)線程的中斷標(biāo)志位是否為true。 public boolean isInterrupted() 返回當(dāng)前線程的中斷標(biāo)志位是否為true,并清空中斷標(biāo)志位。 public static boolean interrupted() 表示中斷對(duì)應(yīng)的線程。 public void interrupt()
2、線程對(duì)中斷interrupt()的反應(yīng)
2.1、RUNNABLE:線程在運(yùn)行或具備運(yùn)行條件只是在等待操作系統(tǒng)調(diào)度
舉個(gè)栗子:
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("線程t 執(zhí)行中...");
}
});
t.start();
Thread.sleep(1);
t.interrupt();
System.out.println("main exit");
}RUNNABLE狀態(tài)的線程t被interrupt()后,是否終止中斷線程由線程t自身代碼邏輯決定。
2.2、WAITING/TIMED_WAITING:線程在等待某個(gè)條件或超時(shí)
線程執(zhí)行如下方法會(huì)進(jìn)入WAITING狀態(tài): public final void join() throws InterruptedException public final void wait() throws InterruptedException 線程執(zhí)行如下方法會(huì)進(jìn)入TIMED_WAITING狀態(tài): public final native void wait(long timeout) throws InterruptedException public static native void sleep(long millis) throws InterruptedException public final synchronized void join(long millis) throws InterruptedException
舉個(gè)栗子:
public class ThreadInterrupt {
public static void main(String[] args) {
Thread t = new Thread(() -> {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Thread.interrupted() = " + Thread.interrupted());
//Thread.interrupted() = false
System.out.println("Thread.interrupted() = " + Thread.interrupted());
//Thread.interrupted() = false
}
});
t.start();
t.interrupt();
}
}捕獲到InterruptedException,通常表示希望結(jié)束該線程,線程大概有兩種處理方式:
向上傳遞該異常,這使得該方法也變成了一個(gè)可中斷的方法,需要調(diào)用者進(jìn)行處理。
有些情況,不能向上傳遞異常,比如Thread的run方法,它的聲明是固定的,不能拋出任何受檢異常,這時(shí),應(yīng)該捕獲異常,進(jìn)行合適的清理操作,清理后,一般應(yīng)該調(diào)用Thread的interrupt方法設(shè)置中斷標(biāo)志位,使得其他代碼有辦法知道它發(fā)生了中斷。
2.3、BLOCKED:線程在等待鎖,試圖進(jìn)入同步塊
舉個(gè)栗子:
public class ThreadInterrupt {
private final static Object lockObj = new Object();
private static class MyBlockedThread extends Thread {
@Override
public void run() {
System.out.println("MyBlockedThread.run = " + Thread.currentThread().isInterrupted());
synchronized (lockObj) {
while (!Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().isInterrupted());
}
}
System.out.println("exit");
}
}
public static void main(String[] args) throws InterruptedException {
synchronized (lockObj) {
MyBlockedThread myBlockedThread = new MyBlockedThread();
myBlockedThread.start();
Thread.sleep(3000);
myBlockedThread.interrupt();
myBlockedThread.join(); // join方法會(huì)等待線程執(zhí)行完后返回
}
}
}myBlockedThread.join();該行代碼放開(kāi)注釋掉情況下:線程一直等待鎖 BLOCKED。
com.michael.ThreadInterrupt.MyBlockedThread.run = false
myBlockedThread.join();該行代碼注釋掉情況下:因?yàn)橹骶€程不再等待線程myBlockedThread結(jié)束,釋放鎖lock后,線程myBlockedThread會(huì)獲得鎖,然后檢測(cè)到發(fā)生了中斷,然后程序退出。
com.michael.ThreadInterrupt.MyBlockedThread.run = false exit
2.4、NEW/TERMINATED:線程還未啟動(dòng)或已結(jié)束
舉個(gè)栗子:
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
System.out.println("線程t 執(zhí)行...");
});
t.interrupt();
System.out.println("NEW = " + t.isInterrupted());
t.start();
Thread.sleep(100);
t.interrupt();
System.out.println("TERMINATE = " + t.isInterrupted());
}
============ 執(zhí)行結(jié)果 ============
NEW = false
線程t 執(zhí)行...
TERMINATE = false2.5、IO操作
如果線程在等待IO操作,尤其是網(wǎng)絡(luò)IO,則會(huì)有一些特殊的處理。
- 如果IO通道是可中斷的,即實(shí)現(xiàn)了
InterruptibleChannel接口,則線程的中斷標(biāo)志位會(huì)被設(shè)置,同時(shí)線程會(huì)收到異常ClosedByInterruptException。 - 如果線程阻塞于
Selector調(diào)用,則線程的中斷標(biāo)志位會(huì)被設(shè)置,同時(shí)阻塞的調(diào)用會(huì)立即返回。 InputStream的read調(diào)用,該操作是不可中斷的,如果流中沒(méi)有數(shù)據(jù),read會(huì)阻塞 (但線程狀態(tài)依然是RUNNABLE),且不響應(yīng)interrupt(),與synchronized類似,調(diào)用interrupt()只會(huì)設(shè)置線程的中斷標(biāo)志,而不會(huì)真正"中斷"。
3、關(guān)于中斷的經(jīng)驗(yàn)
Java中取消/關(guān)閉線程技術(shù)是中斷,但它是一種協(xié)作機(jī)制,不會(huì)強(qiáng)制終止線程。線程在不同狀態(tài)和IO操作時(shí)對(duì)中斷的反應(yīng)有所不同。
作為線程的實(shí)現(xiàn)者:應(yīng)該提供明確的取消/關(guān)閉方法,并用文檔描述清楚其行為。
作為線程的調(diào)用者:應(yīng)該使用其取消/關(guān)閉方法,而不是貿(mào)然調(diào)用interrupt()方法。
到此這篇關(guān)于java中線程中斷的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)java 線程中斷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot用配置影響B(tài)ean加載@ConditionalOnProperty
這篇文章主要為大家介紹了SpringBoot用配置影響B(tài)ean加載@ConditionalOnProperty示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
java servlet結(jié)合Oracle搭建java的web開(kāi)發(fā)環(huán)境
今天我將與大家分享一下我學(xué)JAVA WEB寫的一些小實(shí)例 ,我個(gè)人是不太喜歡書本上的晦澀的概念的,所以我花了更多的時(shí)間在一些應(yīng)用實(shí)例上,我覺(jué)得這樣的學(xué)習(xí)方式很適合我,由簡(jiǎn)到繁,由淺入深2015-12-12
SpringBoot返回對(duì)象時(shí),如何將Long類型轉(zhuǎn)換為String
這篇文章主要介紹了SpringBoot返回對(duì)象時(shí),實(shí)現(xiàn)將Long類型轉(zhuǎn)換為String,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
spring boot 項(xiàng)目中使用thymeleaf模板的案例分析
這篇文章主要介紹了spring boot 項(xiàng)目中使用thymeleaf模板的案例分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
SpringBoot實(shí)現(xiàn)熱部署的方式總結(jié)
所謂熱部署,就是在應(yīng)用正在運(yùn)行的時(shí)候升級(jí)軟件,卻不需要重新啟動(dòng)應(yīng)用,對(duì)于Java來(lái)說(shuō),熱部署就是在運(yùn)行時(shí)更新Java類文件,本文將深入探討SpringBoot有哪些方式可以實(shí)現(xiàn)熱部署,感興趣的朋友可以小編一探討學(xué)習(xí)2023-06-06

