Java終止線程的幾種方式實(shí)例總結(jié)
一、正常運(yùn)行結(jié)束
所謂正常運(yùn)行結(jié)束,就是程序正常運(yùn)行結(jié)束,線程自動(dòng)結(jié)束。
public class ThreadTest extends Thread {
public void run() {
//do something
}
} 二、使用退出標(biāo)志退出線程
一般run()方法執(zhí)行完,線程就會(huì)正常結(jié)束,然而,常常有些線程是伺服線程。他們需要長(zhǎng)時(shí)間的運(yùn)行,只有在外部某些條件滿足的情況下,才能關(guān)閉這些線程。使用一個(gè)變量來(lái)控制循環(huán),例如:最直接的方法就是設(shè)一個(gè)boolean類型的標(biāo)志,并通過(guò)設(shè)置這個(gè)標(biāo)志位true或false來(lái)控制while循環(huán)是否退出,下面放代碼:
public class ThreadTest extends Thread {
public volatile boolean exit = false;
public void run() {
while (!exit){
//do something
}
}
} 三、interrupt方法結(jié)束線程
使用interrupt()方法來(lái)中斷線程是分兩種情況的:
- 線程處于阻塞狀態(tài):如使用了sleep(),同步鎖的wait(),socket中的receiver(),accept()等方法時(shí),會(huì)使線程處于阻塞狀態(tài)。當(dāng)調(diào)用線程interrupt()方法時(shí),會(huì)拋出InterruptException異常。阻塞中的那個(gè)方法拋出此異常,通過(guò)代碼可以捕獲此異常,然后跳出循環(huán)狀態(tài),從而讓我們有機(jī)會(huì)結(jié)束這個(gè)線程的執(zhí)行。并不是只要調(diào)用interrupt()方法,線程就會(huì)結(jié)束,實(shí)際上是不正確的,一定要先捕獲InterruptException異常之后通過(guò)break來(lái)跳出循環(huán),才能正常結(jié)束run()方法。
- 線程未處于阻塞狀態(tài):使用isInterrupted()判斷線程的中斷標(biāo)志來(lái)退出循環(huán)。當(dāng)使用interrupt()方法時(shí),中斷標(biāo)志就會(huì)為true,和使用自定義的標(biāo)志來(lái)控制循環(huán)是一樣的道理。
public class ThreadTest extends Thread {
public void run() {
while(!isInterrupted()) {
try {
Thread.sleep(5*1000);
} catch(InterruptedException e) {
e.printStackTrace();
break;//捕獲到異常之后,執(zhí)行break跳出循環(huán)
}
}
}
}四、stop()方法終止線程(不安全)
我們可以直接使用thread.stop()來(lái)強(qiáng)行終止線程,但是stop()方法是很危險(xiǎn)的,就想突然關(guān)閉電源一樣。這樣子可能機(jī)會(huì)產(chǎn)生不可預(yù)料的結(jié)果,不安全主要是:
- thread.stop()調(diào)用之后,創(chuàng)建子線程的線程就會(huì)拋出ThreadDeatherror的錯(cuò)誤,并且會(huì)釋放子線程所持有的所有鎖。一般任何進(jìn)行加鎖的代碼塊,都是為了保護(hù)數(shù)據(jù)的一致性,如果在調(diào)用thread.stop()后導(dǎo)致了該線程所持有的所有的鎖突然釋放,那么被保護(hù)的數(shù)據(jù)就可能呈現(xiàn)不一致性,其他線程在使用這些被破壞的數(shù)據(jù)時(shí),有可能導(dǎo)致一些很奇怪的應(yīng)用程序錯(cuò)誤。因此,并不推薦使用stop()方法來(lái)終止線程。
五、線程相關(guān)
5.1 sleep()和wait()區(qū)別
- 對(duì)于sleep()方法,我們首先要知道該方法是屬于Thread類中的,而wait()方法,則是屬于Object類中的。
- sleep()方法導(dǎo)致了程序暫停執(zhí)行指定的時(shí)間,讓出CPU給其他線程,但是它依然處于監(jiān)控狀態(tài),當(dāng)指定時(shí)間到了又會(huì)自動(dòng)恢復(fù)運(yùn)行狀態(tài)。
- 調(diào)用sleep()方法的過(guò)程中,線程不會(huì)釋放對(duì)象鎖。
- 調(diào)用wait()方法的時(shí)候,線程會(huì)釋放對(duì)象鎖,進(jìn)入等待此對(duì)象的等待鎖定池,只有針對(duì)此對(duì)象調(diào)用notify()方法后本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備獲取對(duì)象鎖進(jìn)入運(yùn)行狀態(tài)。
5.2 start()和run()的區(qū)別
- start()方法來(lái)啟動(dòng)線程,真正實(shí)現(xiàn)了多線程運(yùn)行。這時(shí)無(wú)需等待run()方法體代碼執(zhí)行完畢,可以繼續(xù)執(zhí)行下面的代碼。
- 通過(guò)調(diào)用Thread類的start()方法來(lái)啟動(dòng)一個(gè)線程,此時(shí)線程是處于就緒狀態(tài),并沒(méi)有運(yùn)行。
- 方法run()稱為線程體,它包含了要執(zhí)行的這個(gè)線程的內(nèi)容,次線程終止。然后CPU在調(diào)度其他線程。
5.3 Java后臺(tái)線程(守護(hù)線程)
- 定義:守護(hù)線程–也稱“服務(wù)線程”,他是后臺(tái)線程,它有一個(gè)特性,即為用戶線程 提供 公共服務(wù),在沒(méi)有用戶線程可服務(wù)時(shí)會(huì)自動(dòng)離開(kāi)。
- 優(yōu)先級(jí):守護(hù)線程的優(yōu)先級(jí)比較低,用于為系統(tǒng)中的其它對(duì)象和線程提供服務(wù)。
設(shè)置:通過(guò)setDaemon(true)來(lái)設(shè)置線程為“守護(hù)線程”;將一個(gè)用戶線程設(shè)置為守護(hù)線程的方式是在 線程對(duì)象創(chuàng)建 之前 用線程對(duì)象的setDaemon方法。 - 在Daemon線程中產(chǎn)生的新線程也是Daemon的。
- 守護(hù)線程則是JVM級(jí)別的,以Tomcat 為例,如果你在Web 應(yīng)用中啟動(dòng)一個(gè)線程,這個(gè)線程的生命周期并不會(huì)和Web應(yīng)用程序保持同步。也就是說(shuō),即使你停止了Web應(yīng)用,這個(gè)線程依舊是活躍的。
- example: 垃圾回收線程就是一個(gè)經(jīng)典的守護(hù)線程,當(dāng)我們的程序中不再有任何運(yùn)行的Thread,程序就不會(huì)再產(chǎn)生垃圾,垃圾回收器也就無(wú)事可做,所以當(dāng)垃圾回收線程是JVM上僅剩的線程時(shí),垃圾回收線程會(huì)自動(dòng)離開(kāi)。它始終在低級(jí)別的狀態(tài)中運(yùn)行,用于實(shí)時(shí)監(jiān)控和管理系統(tǒng)中的可回收資源。
- 生命周期:守護(hù)進(jìn)程(Daemon)是運(yùn)行在后臺(tái)的一種特殊進(jìn)程。它獨(dú)立于控制終端并且周期性地執(zhí)行某種任務(wù)或等待處理某些發(fā)生的事件。也就是說(shuō)守護(hù)線程不依賴于終端,但是依賴于系統(tǒng),與系統(tǒng)“同生共死”。當(dāng)JVM中所有的線程都是守護(hù)線程的時(shí)候,JVM就可以退出了;如果還有一個(gè)或以上的非守護(hù)線程則JVM不會(huì)退出。
總結(jié)
到此這篇關(guān)于Java終止線程的幾種方式的文章就介紹到這了,更多相關(guān)Java終止線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis-Plus 如何實(shí)現(xiàn)連表查詢的示例代碼
這篇文章主要介紹了MyBatis-Plus 如何實(shí)現(xiàn)連表查詢的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Java編程中常見(jiàn)的六大死鎖場(chǎng)景及其應(yīng)對(duì)策略詳解
在多線程編程中,死鎖是一個(gè)令人頭疼卻又無(wú)法回避的問(wèn)題,本文將系統(tǒng)梳理Java開(kāi)發(fā)中常見(jiàn)的死鎖場(chǎng)景,分析其成因,并提供實(shí)用的解決方案,幫助開(kāi)發(fā)者構(gòu)建更加可靠的并發(fā)應(yīng)用2025-09-09
SpringBoot實(shí)現(xiàn)本地文件存儲(chǔ)及預(yù)覽過(guò)程
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)本地文件存儲(chǔ)及預(yù)覽過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
Java?中的排序Comparable?與?Comparator?的使用與區(qū)別對(duì)比解析
本文給大家介紹Java中的排序Comparable與Comparator的使用與區(qū)別對(duì)比,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2025-09-09
Java ArrayList的底層實(shí)現(xiàn)方法
今天小編就為大家分享一篇Java ArrayList的底層實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
java對(duì)象類型轉(zhuǎn)換和多態(tài)性(實(shí)例講解)
下面小編就為大家?guī)?lái)一篇java對(duì)象類型轉(zhuǎn)換和多態(tài)性(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10
IntelliJ?idea報(bào)junit?no?tasks?available問(wèn)題的解決辦法
這篇文章主要給大家介紹了關(guān)于IntelliJ?idea報(bào)junit?no?tasks?available問(wèn)題的解決辦法,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-11-11

