線(xiàn)程的生命周期
Java語(yǔ)言中定義了5種線(xiàn)程狀態(tài),在任意一個(gè)時(shí)間點(diǎn),一個(gè)線(xiàn)程只能有且只有其中一種狀態(tài),這5種狀態(tài)是:
- 新建(New):創(chuàng)建后尚未啟動(dòng)的線(xiàn)程處于這種狀態(tài)。
- 運(yùn)行(Runable):包括了操作系統(tǒng)線(xiàn)程狀態(tài)中的Running和Ready,也就是處于此狀態(tài)的線(xiàn)程有可能正在執(zhí)行,也有可能正在等待著CPU為它分配執(zhí)行時(shí)間。
- 無(wú)限期等待(Waiting):處于這種狀態(tài)的線(xiàn)程不會(huì)被分配CPU執(zhí)行時(shí)間,它們要等待被其他線(xiàn)程顯式地喚醒。以下方法會(huì)讓線(xiàn)程陷入無(wú)限期的等待狀態(tài):
- 沒(méi)有設(shè)置timeout參數(shù)的Object.wait()方法;
- 沒(méi)有設(shè)置timeout參數(shù)的Thread.join()方法;
- LockSupport.park()方法;
- 限期等待(Timed Waiting):處于這種狀態(tài)的線(xiàn)程也不會(huì)被分配CPU執(zhí)行時(shí)間,不過(guò)無(wú)須等待被其他線(xiàn)程顯式地喚醒,在一定時(shí)間之后它們會(huì)由操作系統(tǒng)自動(dòng)喚醒。以下方法會(huì)讓線(xiàn)程進(jìn)入限期等待狀態(tài):
- Thread.sleep()方法;
- 設(shè)置了timeout參數(shù)的Object.wait()方法;
- 設(shè)置了timeout參數(shù)的Thread.join()方法;
- LockSupport.parkNanos()方法;
- LockSupport.parkUntil()方法;
- 阻塞(Blocked):線(xiàn)程被阻塞了,“阻塞狀態(tài)”與“等待狀態(tài)”的區(qū)別是:“阻塞狀態(tài)”在等待著獲取到一個(gè)排它鎖,這個(gè)事件將在另外一個(gè)線(xiàn)程放棄這個(gè)鎖的時(shí)候發(fā)生;而“等待狀態(tài)”則是在等待一段時(shí)間,或者喚醒動(dòng)作的發(fā)生。在程序等待進(jìn)入同步區(qū)域(synchronized)的時(shí)候,線(xiàn)程將進(jìn)入這種狀態(tài)。
- 結(jié)束(Terminated):已終止的線(xiàn)程狀態(tài),線(xiàn)程已經(jīng)結(jié)束執(zhí)行。
線(xiàn)程間的狀態(tài)轉(zhuǎn)換
1、新建(New)
新創(chuàng)建了一個(gè)線(xiàn)程對(duì)象,還未調(diào)用start()方法。
Thread thread = new Thread();
2、就緒(Ready)
線(xiàn)程對(duì)象創(chuàng)建后,其他線(xiàn)程(比如main線(xiàn)程)調(diào)用了該對(duì)象的start()方法。該狀態(tài)的線(xiàn)程位于可運(yùn)行線(xiàn)程池中,等待被線(xiàn)程調(diào)度選中 獲取cpu 的使用權(quán) 。
3、運(yùn)行中(Running)
可運(yùn)行狀態(tài)(runnable)的線(xiàn)程獲得了cpu 時(shí)間片(timeslice) ,執(zhí)行程序代碼。
4、限期等待(Timed Waiting)
也可以稱(chēng)作 TIMED_WAITING(有等待時(shí)間的等待狀態(tài))。
線(xiàn)程主動(dòng)調(diào)用以下方法:
- Thread.sleep方法;
- Object的wait方法,帶有時(shí)間;
- Thread.join方法,帶有時(shí)間;
- LockSupport的parkNanos方法,帶有時(shí)間。
5、無(wú)限期等待(Waiting)
運(yùn)行中(Running)的線(xiàn)程執(zhí)行了以下方法:
- Object的wait方法,并且沒(méi)有使用timeout參數(shù);
- Thread的join方法,沒(méi)有使用timeout參數(shù);
- LockSupport的park方法;
- Conditon的await方法。
6、阻塞(Blocked)
阻塞狀態(tài)是指線(xiàn)程因?yàn)槟撤N原因放棄了cpu 使用權(quán),暫時(shí)停止運(yùn)行。直到線(xiàn)程進(jìn)入可運(yùn)行(runnable)狀態(tài),才有機(jī)會(huì)再次獲得cpu timeslice 轉(zhuǎn)到運(yùn)行(running)狀態(tài)。阻塞的情況分兩種:
- 同步阻塞:運(yùn)行(running)的線(xiàn)程進(jìn)入了一個(gè)synchronized方法,若該同步鎖被別的線(xiàn)程占用,則JVM會(huì)把該線(xiàn)程放入鎖池(lock pool)中。
- 其他阻塞:運(yùn)行(running)的線(xiàn)程發(fā)出了I/O請(qǐng)求時(shí),JVM會(huì)把該線(xiàn)程置為阻塞狀態(tài)。當(dāng)I/O處理完畢時(shí),線(xiàn)程重新轉(zhuǎn)入可運(yùn)行(runnable)狀態(tài)。
7、結(jié)束(Terminated)
線(xiàn)程run()、main() 方法執(zhí)行結(jié)束,或者因異常退出了run()方法,則該線(xiàn)程結(jié)束生命周期。