Java結(jié)束線程的三種方法及該如何選擇
java常用的結(jié)束一個運行中的線程的方法有3中:使用退出標(biāo)志,使用interrupt方法,使用stop方法。
1.使用退出標(biāo)志
即在線程內(nèi)部定義一個bool變量來判斷是否結(jié)束當(dāng)前的線程:
public class ThreadSafe extends Thread {
public volatile boolean exit = false;
public void run() {
while (!exit){
//do work
}
}
public static void main(String[] args) throws Exception {
ThreadFlag thread = new ThreadFlag();
thread.start();
sleep(5000); // 主線程延遲5秒
thread.exit = true; // 終止線程thread
thread.join();
System.out.println("線程退出!");
}
}
這種情況一般是將線程的任務(wù)放在run方法中的一個while循環(huán)中,而由這個bool變量來對while循環(huán)進行控制。
2.使用interrupt方法
這種方法需要判斷當(dāng)前的線程所處于的狀態(tài):
(1)當(dāng)前線程處于阻塞狀態(tài)時
線程處于阻塞狀態(tài)一般是在使用了 sleep,同步鎖的 wait,socket 中的 receiver,accept 等方法時,會使線程處于阻塞狀態(tài)。
public class ThreadInterrupt extends Thread {
public void run() {
try {
sleep(50000); // 延遲50秒
}
catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] args) throws Exception {
Thread thread = new ThreadInterrupt();
thread.start();
System.out.println("在50秒之內(nèi)按任意鍵中斷線程!");
System.in.read();
thread.interrupt();
thread.join();
System.out.println("線程已經(jīng)退出!");
}
}
注意這種情況寫,使用 interrupt 方法結(jié)束線程的時候,一定要先捕獲 InterruptedException 異常之后通過 break 來跳出循環(huán),才能正常結(jié)束 run 方法。
(2)線程未處于阻塞狀態(tài)時
使用 isInterrupted() 判斷線程的中斷標(biāo)志來退出循環(huán)。當(dāng)使用 interrupt() 方法時,中斷標(biāo)志就會置 true,和使用自定義的標(biāo)志來控制循環(huán)是一樣的道理。
public class ThreadSafe extends Thread {
public void run() {
while (!isInterrupted()) { //非阻塞過程中通過判斷中斷標(biāo)志來退出
try {
Thread.sleep(5*1000); //阻塞過程捕獲中斷異常來退出
} catch (InterruptedException e) {
e.printStackTrace();
break; //捕獲到異常之后,執(zhí)行 break 跳出循環(huán)
}
}
}
}
3.使用stop方法來結(jié)束線程
public class Main {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
myThread.start();
Thread.sleep(3000); // 間隔3秒后
myThread.stop(); // 結(jié)束線程
System.out.println("結(jié)束了");
}
}
4.結(jié)束方法的選擇
建議使用標(biāo)志位和interrupt方法來結(jié)束線程,stop方法已經(jīng)不建議再被使用了。
因為采用 stop 是不安全的,主要影響點如下:
- thread.stop() 調(diào)用之后,創(chuàng)建子線程的線程就會拋出 ThreadDeatherror 的錯誤;
- 調(diào)用 stop 會釋放子線程所持有的所有鎖。導(dǎo)致了該線程所持有的所有鎖的突然釋放(不可控制),那么被保護數(shù)據(jù)就有可能呈現(xiàn)不一致性。
以上就是Java結(jié)束線程的三種方法及該如何選擇的詳細內(nèi)容,更多關(guān)于Java 結(jié)束線程的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot2.動態(tài)@Value的實現(xiàn)方式
這篇文章主要介紹了SpringBoot2.動態(tài)@Value的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
現(xiàn)代高效的java構(gòu)建工具gradle的快速入門
和Maven一樣,Gradle只是提供了構(gòu)建項目的一個框架,真正起作用的是Plugin,本文主要介紹了gradle入門,文中通過示例代碼介紹的非常詳細,感興趣的小伙伴們可以參考一下2021-11-11

