Java開發(fā)中線程是經(jīng)常用到的技術(shù)卿叽,那么讓我們來回顧一下一些線程中經(jīng)炒布眩考慮的問題吧
1滋早、線程分為用戶線程和守護(hù)線程,有什么區(qū)別2砌们、線程有哪些運(yùn)行狀態(tài)
一杆麸、什么是線程
?????? 線程,一個(gè)執(zhí)行實(shí)體浪感,正在執(zhí)行的程序昔头,擔(dān)當(dāng)分配系統(tǒng)資源(CPU、內(nèi)存)的實(shí)體影兽。一個(gè)完整的線程包括揭斧,需要運(yùn)行的邏輯和需要運(yùn)行需要的資源。
二峻堰、線程的狀態(tài)
線程有哪些狀態(tài)呢讹开,在Thread的代碼中的State枚舉已經(jīng)很清楚了
public enum State {NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED;}
線程的狀態(tài)實(shí)際是7種,新建捐名、就緒旦万、運(yùn)行、阻塞镶蹋、等待成艘、超時(shí)等待既绩、終止芹壕。不過一般將就緒和運(yùn)行都算作運(yùn)行中
新建:新建的線程對(duì)象,還未調(diào)用start方法
就緒:已經(jīng)具備了運(yùn)行條件虐呻,等待CPU服務(wù)牧氮,這個(gè)狀態(tài)下琼腔,線程在就緒隊(duì)列中等待
運(yùn)行:線程具備運(yùn)行條件,并獲得了CPU資源
阻塞:線程被掛起踱葛,一般是加鎖獲取同步狀態(tài)被阻塞丹莲,放到阻塞隊(duì)列中光坝,阻塞狀態(tài)消除后,會(huì)進(jìn)入就緒狀態(tài)
等待:等待狀態(tài)表示當(dāng)前線程需要等待其他線程做出一些特定動(dòng)作(等待通知機(jī)制)
超時(shí)等待:在等待的基礎(chǔ)上甥材,加上一定時(shí)間后返回就緒狀態(tài)
終止:線程已經(jīng)運(yùn)行完畢
那么這些狀態(tài)是如何切換的呢盯另,借用java并發(fā)編程藝術(shù)中的一張圖
start方法調(diào)用后進(jìn)入運(yùn)行狀態(tài),wait洲赵、sleep等方法進(jìn)入等待狀態(tài)或鸳惯,yeild方法進(jìn)入就緒狀態(tài),lock和synchronized進(jìn)入阻塞狀態(tài)
三叠萍、線程的分類
線程可以分為守護(hù)線程和用戶線程兩種芝发,那么什么是用戶線程,什么是守護(hù)線程呢苛谷?
? 1辅鲸、用戶線程
用戶線程就是我們平時(shí)使用的用來處理邏輯的線程。
2腹殿、守護(hù)線程
守護(hù)線程独悴,是服務(wù)線程,程序運(yùn)行時(shí)在后臺(tái)提供的一種通用服務(wù)的線程锣尉。最常見的就是jvm的垃圾回收線程刻炒。
那么守護(hù)線程相對(duì)普通的線程有什么不同,是用來做什么的呢自沧?
1)守護(hù)線程主要為其他線程提供服務(wù)的2)在jvm中所有用戶線程停止運(yùn)行后坟奥,只剩守護(hù)線程了,那么jvm也會(huì)退出
了解了守護(hù)線程的特點(diǎn)了,那么用戶線程和守護(hù)線程運(yùn)行的實(shí)際效果呢暂幼?
首先看下Thread類型中的setDaemon方法筏勒,通過這個(gè)方法來設(shè)置是守護(hù)線程和用戶線程,默認(rèn)是用戶線程
首先旺嬉,先創(chuàng)建一個(gè)用戶線程,代碼如下
public static void main(String[] args){
Thread task = new Thread(new Runnable(){
@Override public void run() {
System.out.println("start thread ..." +System.currentTimeMillis());
try {Thread.sleep(5000);} catch (InterruptedException e){e.printStackTrace();}
System.out.println("end thread..."+System.currentTimeMillis());}});
task.start();
try {Thread.sleep(2000);} catch (InterruptedException e){e.printStackTrace();}
System.out.println("end main..."+System.currentTimeMillis());}
運(yùn)行結(jié)果
startthread...1589291388584
endmain...1589291390585
endthread...1589291393585
很明顯的看到在main函數(shù)結(jié)束以后厨埋,等待線程技術(shù)了邪媳,jvm才停止運(yùn)行
那么對(duì)代碼做一下修改,改為守護(hù)線程呢荡陷,代碼如下
public static void main(String[] args){
Thread task =newThread(newRunnable(){
@Override
public void run() {System.out.println("start thread..."+System.currentTimeMillis());
try{Thread.sleep(5000);}catch(InterruptedException e){e.printStackTrace();}
System.out.println("end thread..."+System.currentTimeMillis());? ? ? ? }? ? });t
ask.setDaemon(true);? ?
task.start();
try{Thread.sleep(2000);}catch(InterruptedException e){e.printStackTrace();}
System.out.println("end main..."+System.currentTimeMillis());??}
運(yùn)行結(jié)果
startthread...1589291497224
endmain...1589291499225
在main函數(shù)結(jié)束以后雨效,jvm就退出來
守護(hù)線程的應(yīng)用場(chǎng)景:
?????? 1、為用戶線程提供服務(wù)的線程
?????? 2废赞、在任何情況下都能關(guān)閉的線程(文件的讀寫等不能直接關(guān)閉的操作最好不要使用守護(hù)線程)
守護(hù)線程的注意事項(xiàng)
?????? 1徽龟、守護(hù)線程狀態(tài)的設(shè)置必須在線程啟動(dòng)之前
?????? 2、守護(hù)線程中創(chuàng)建的線程也是守護(hù)線程
那么關(guān)于線程的知識(shí)點(diǎn)先說到這里
上文中說到線程狀態(tài)的切換了唉地,分享一個(gè)經(jīng)常討論的問題sleep和wait的區(qū)別
常規(guī)的答案
1据悔、sleep沒有釋放鎖传透,wait釋放了鎖
2、sleep是Thread的靜態(tài)方法极颓,wait是鎖對(duì)象的方法
3朱盐、sleep是休眠一段時(shí)間,wait需要notify喚醒
?????? 是否感覺說的有些太淺了菠隆,怎么可以聊的深一點(diǎn)呢
?????? 分別說一下sleep和wait從開始休眠到喚醒的狀態(tài)變化
?????? 1兵琳、sleep被調(diào)用后,釋放CPU資源骇径,并在指定時(shí)間內(nèi)不再去爭(zhēng)奪CPU資源躯肌,相當(dāng)于告訴操作系統(tǒng),在N時(shí)間內(nèi)不需要管我了破衔,這個(gè)過程中線程會(huì)進(jìn)入等待隊(duì)列中清女。當(dāng)休眠時(shí)間結(jié)束以后,線程進(jìn)入就緒狀態(tài)运敢,并進(jìn)入就緒隊(duì)列校仑,等待分配系統(tǒng)資源。
?????? 這里經(jīng)常會(huì)有一個(gè)誤區(qū)传惠,就是認(rèn)為在線程等到時(shí)間結(jié)束后迄沫,會(huì)直接進(jìn)入運(yùn)行狀態(tài)。線程只是進(jìn)入就緒狀態(tài)卦方。
?????? 現(xiàn)在了解了sleep調(diào)用過程中發(fā)生了什么羊瘩,那么可以考慮下,在線程代碼中會(huì)經(jīng)常發(fā)現(xiàn)有Thread.sleep(0)這種休眠0毫秒操作盼砍,這是為了什么呢尘吗?
?????? 2、wait在調(diào)用的時(shí)候浇坐,首先釋放鎖狀態(tài)睬捶,然后線程進(jìn)入到等待狀態(tài),當(dāng)其他線程調(diào)用notify時(shí)近刘,會(huì)隨機(jī)喚醒一個(gè)等到線程擒贸,個(gè)人理解是把線程移入鎖對(duì)象的阻塞隊(duì)列當(dāng)中,然后等到獲取鎖狀態(tài)觉渴,進(jìn)入運(yùn)行狀態(tài)介劫。如果調(diào)用notifyAll方法會(huì)把所有的線程都喚醒,去搶占鎖案淋,在搶占結(jié)束以后座韵,沒有獲取到鎖的線程進(jìn)入阻塞狀態(tài)。
?關(guān)于Thread先說到這里踢京,如果有疑問可以留言誉碴。
更多好文章可以關(guān)注公眾號(hào)?MG驛站?宦棺,聯(lián)系作者可后臺(tái)留言
相關(guān)文章