深入探究Java線程的狀態(tài)與生命周期
一、線程的狀態(tài)
NEW: 安排了工作, 還未開(kāi)始行動(dòng)
RUNNABLE: 可工作的. 又可以分成正在工作中和即將開(kāi)始工作.
BLOCKED: 這幾個(gè)都表示排隊(duì)等著其他事情
WAITING: 這幾個(gè)都表示排隊(duì)等著其他事情
TIMED_WAITING: 這幾個(gè)都表示排隊(duì)等著其他事情
TERMINATED: 工作完成了
新建(初始)
當(dāng)繼承Thread類(lèi)和實(shí)現(xiàn)了Runnable接口,就可以創(chuàng)建線程,新建一個(gè)對(duì)象就是初始狀態(tài)
就緒(可運(yùn)行)
- 調(diào)用線程的start()方法,此線程進(jìn)入可運(yùn)行狀態(tài)。
- 當(dāng)前線程sleep()方法結(jié)束,其他線程join()結(jié)束,等待用戶輸入完畢,某個(gè)線程拿到對(duì)象鎖,這些線程也將進(jìn)入可運(yùn)行狀態(tài)。
- 當(dāng)前線程時(shí)間片用完了,調(diào)用當(dāng)前線程的yield()方法,當(dāng)前線程進(jìn)入可運(yùn)行狀態(tài)。
- 鎖池里的線程拿到對(duì)象鎖后,進(jìn)入可運(yùn)行狀態(tài)。
運(yùn)行
可運(yùn)行狀態(tài)(runnable)的線程獲得了cpu 時(shí)間片(timeslice) ,執(zhí)行程序代碼,就到了運(yùn)行狀態(tài)
阻塞
阻塞狀態(tài)是指線程因?yàn)槟撤N原因放棄了cpu 使用權(quán),也即讓出了cpu 時(shí)間片,暫時(shí)停止運(yùn)行。直到線程進(jìn)入可運(yùn)行(runnable)狀態(tài),才有機(jī)會(huì)再次獲得cpu 時(shí)間片轉(zhuǎn)到運(yùn)行(running)狀態(tài)
- 當(dāng)前線程T調(diào)用Thread.sleep()方法,當(dāng)前線程進(jìn)入阻塞狀態(tài)。
- 運(yùn)行在當(dāng)前線程里的其它線程t2調(diào)用join()方法,當(dāng)前線程進(jìn)入阻塞狀態(tài)。
- 等待用戶輸入的時(shí)候,當(dāng)前線程進(jìn)入阻塞狀態(tài)
死亡
- 當(dāng)線程的run()方法完成時(shí),或者主線程的main()方法完成時(shí),我們就認(rèn)為它死去。這個(gè)線程對(duì)象也許是活的,但是,它已經(jīng)不是一個(gè)單獨(dú)執(zhí)行的線程。線程一旦死亡,就不能復(fù)生。
- 在一個(gè)死去的線程上調(diào)用start()方法,會(huì)拋出java.lang.IllegalThreadStateException異常
二、線程的狀態(tài)轉(zhuǎn)移
NEW , RUNNABLE ,TERMINATED 狀態(tài)的轉(zhuǎn)移
使用 isAlive 方法判定線程的存活狀態(tài)
public class ThreadStateTransfer { public static void main(String[] args) throws InterruptedException { Thread t = new Thread(() -> { for (int i = 0; i < 1000_0000; i++) { } }, "李四"); System.out.println(t.getName() + ": " + t.getState());; t.start(); while (t.isAlive()) { System.out.println(t.getName() + ": " + t.getState());; } System.out.println(t.getName() + ": " + t.getState());; } }
yield() 方法,讓出 CPU執(zhí)行權(quán)
/** * yield讓出CPU執(zhí)行權(quán) */ public class ThreadYield { public static void main(String[] args) { Thread thread = new Thread(() ->{ Thread t1 = Thread.currentThread(); for (int i = 0; i < 10; i++) { //讓出CPU執(zhí)行權(quán) Thread.yield(); System.out.println("執(zhí)行了線程" + t1.getName()); } },"張三"); thread.start(); //創(chuàng)建并啟動(dòng)線程 new Thread(() -> { Thread t1 = Thread.currentThread(); for (int i = 0; i < 10; i++) { System.out.println("執(zhí)行了線程" + t1.getName()); } },"李四").start(); }
結(jié)論
yield 不改變線程的狀態(tài), 但是會(huì)重新去排隊(duì)
三、線程的生命周期
- 新建:創(chuàng)建線程對(duì)象
- 就緒:線程有執(zhí)行資格,沒(méi)有執(zhí)行權(quán)
- 運(yùn)行:有執(zhí)行資格,有執(zhí)行權(quán)
- 阻塞:由于一些操作讓線程改變了狀態(tài),沒(méi)有執(zhí)行資格,沒(méi)有執(zhí)行權(quán),另一些操作可以把它給激活,激活處于就緒狀態(tài)
- 死亡:線程對(duì)象變成垃圾,等待被回收
到此這篇關(guān)于深入探究Java線程的狀態(tài)與生命周期的文章就介紹到這了,更多相關(guān)Java線程狀態(tài)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于@Component注解的含義說(shuō)明
這篇文章主要介紹了關(guān)于@Component注解的含義說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11Spring前后端跨域請(qǐng)求設(shè)置代碼實(shí)例
這篇文章主要介紹了Spring前后端跨域請(qǐng)求設(shè)置代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07分布式服務(wù)Dubbo+Zookeeper安全認(rèn)證實(shí)例
下面小編就為大家分享一篇分布式服務(wù)Dubbo+Zookeeper安全認(rèn)證實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12淺談shiro的SecurityManager類(lèi)結(jié)構(gòu)
下面小編就為大家?guī)?lái)一篇淺談shiro的SecurityManager類(lèi)結(jié)構(gòu)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07關(guān)于JSONObject.toJSONString出現(xiàn)地址引用問(wèn)題
這篇文章主要介紹了關(guān)于JSONObject.toJSONString出現(xiàn)地址引用問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Struts2實(shí)現(xiàn)對(duì)action請(qǐng)求對(duì)象的攔截操作方法
這篇文章主要介紹了Struts2實(shí)現(xiàn)對(duì)action請(qǐng)求對(duì)象的攔截操作方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-11-11