在Java中可以使用以下方法來結(jié)束一個線程:
java.lang.Thread類中包含了一些常用的方法藤树,如:start(),stop(),stop(Throwable),suspend(),destory(),resume()椿疗。通過這些方法灯节,我們可以對線程進行方便的操作靶溜,但是這些方法中所袁,只有start()方法得到了保留糟需。
在JDK幫助文檔以及Sun公司的一篇文章《Why are Thread stop,Thread suspend and Thread resume Deprecated旅赢?》中都講解了舍棄這些方法的原因。
簡單來說是因為:使用stop方法雖然可以 強行終止 正在運行或掛起的線程激捏,但使用stop方法是很危險的设塔,就像突然關(guān)閉計算機電源,而不是按正常程序關(guān)機一樣远舅,可能會產(chǎn)生不可預(yù)料的結(jié)果闰蛔,因此,并不推薦使用stop方法來終止線程图柏。
一序六、使用標志位
當run方法執(zhí)行完后,線程就會退出蚤吹。但是有時run方法是永遠不會結(jié)束的例诀,如在服務(wù)端程序中使用線程進行監(jiān)聽客戶端請求,或是其他的需要循環(huán)處理的任務(wù)距辆。
在線程的執(zhí)行邏輯中余佃,設(shè)置一個標志位來判斷是否需要終止線程,將標志位設(shè)置為true跨算,當外部需要終止線程時爆土,將標志位設(shè)置為false,將線程在下一次循環(huán)中檢查該標志位并主動退出循環(huán)從而結(jié)束線程诸蚕。
public class MyThread extends Thread {
private volatile boolean isRunning = true;
public void run() {
while (isRunning) {
// 線程執(zhí)行的邏輯
}
}
public void stopThread() {
isRunning = false;
}
}
二步势、使用interrupt()方法+InterruptedException
如果一個線程由于等待某些事件的發(fā)生而被阻塞,又該怎樣停止該線程呢背犯?
這種情況經(jīng)常會發(fā)生坏瘩,比如當一個線程由于需要等候鍵盤輸入而被阻塞,或者調(diào)用Thread.join()方法漠魏,或者Thread.sleep()方法倔矾,在網(wǎng)絡(luò)中調(diào)用ServerSocket.accept()方法,或者調(diào)用了DatagramSocket.receive()方法時,都有可能導(dǎo)致線程阻塞哪自,使線程處于不可運行狀態(tài)時丰包,即使主線程中將該線程的共享變量設(shè)置為true,但該線程此時根本無法檢查循環(huán)標志壤巷,當然也就無法立即中斷邑彪。
這時建議不要使用stop()方法,而是使用Thread提供的interrupt()方法胧华,因為該方法雖然不會中斷一個正在運行的線程寄症,但是它可以 使一個被阻塞的線程拋出一個中斷異常,從而使線程提前結(jié)束阻塞狀態(tài)矩动,退出阻塞代碼
調(diào)用Thread類的interrupt()方法可以發(fā)送中斷信號給目標線程有巧。在線程的執(zhí)行邏輯中通過檢查isInterrupted()方法或捕獲InterruptException異常來響應(yīng)中斷信號并退出循環(huán)從而結(jié)束線程。
線程處于阻塞狀態(tài)铅忿,如Thread.sleep剪决、wait灵汪、IO阻塞等情況時檀训,調(diào)用interrupt方法后,sleep等方法將會拋出一個InterruptedException
public class MyThread extends Thread {
public void run() {
while (!isInterrupted()) {
// 線程執(zhí)行的邏輯
try {
sleep(1000);
} catch (InterruptedException e) { // 捕獲 InterruptedException 異常
break; // 響應(yīng)中斷信號并退出循環(huán)
}
}
}
}
// 終止線程:
myThread.interrupt();
請注意享言,在上述兩種方式中峻凫,第一種方式是通過自定義變量控制和終止線程序列;第二種方式是通過Java提供的interrupt機制向線程發(fā)送中斷信號览露,然后在線程內(nèi)部進行響應(yīng)荧琼。選擇合適的方式取決于具體需求和場景。