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類(lèi)型的標(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類(lèi)中的,而wait()方法,則是屬于Object類(lèi)中的。
- 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類(lèi)的start()方法來(lái)啟動(dòng)一個(gè)線程,此時(shí)線程是處于就緒狀態(tài),并沒(méi)有運(yùn)行。
- 方法run()稱(chēng)為線程體,它包含了要執(zhí)行的這個(gè)線程的內(nèi)容,次線程終止。然后CPU在調(diào)度其他線程。
5.3 Java后臺(tái)線程(守護(hù)線程)
- 定義:守護(hù)線程–也稱(chēng)“服務(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.type-aliases-package之巨坑的解決
這篇文章主要介紹了mybatis.type-aliases-package之巨坑的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2021-09-09

詳解SpringBoot中異步請(qǐng)求和異步調(diào)用(看完這一篇就夠了)

WebSocket獲取httpSession空指針異常的解決辦法

解決SpringBoot加載application.properties配置文件的坑

SpringCloud實(shí)現(xiàn)文件上傳功能的方法詳解