線程的生命周期
Java語(yǔ)言中定義了5種線程狀態(tài),在任意一個(gè)時(shí)間點(diǎn),一個(gè)線程只能有且只有其中一種狀態(tài)祸泪,這5種狀態(tài)是:
- 新建(New):創(chuàng)建后尚未啟動(dòng)的線程處于這種狀態(tài)。
- 運(yùn)行(Runable):包括了操作系統(tǒng)線程狀態(tài)中的Running和Ready建芙,也就是處于此狀態(tài)的線程有可能正在執(zhí)行没隘,也有可能正在等待著CPU為它分配執(zhí)行時(shí)間。
- 無(wú)限期等待(Waiting):處于這種狀態(tài)的線程不會(huì)被分配CPU執(zhí)行時(shí)間岁钓,它們要等待被其他線程顯式地喚醒升略。以下方法會(huì)讓線程陷入無(wú)限期的等待狀態(tài):
- 沒(méi)有設(shè)置timeout參數(shù)的Object.wait()方法;
- 沒(méi)有設(shè)置timeout參數(shù)的Thread.join()方法屡限;
- LockSupport.park()方法;
- 限期等待(Timed Waiting):處于這種狀態(tài)的線程也不會(huì)被分配CPU執(zhí)行時(shí)間炕倘,不過(guò)無(wú)須等待被其他線程顯式地喚醒钧大,在一定時(shí)間之后它們會(huì)由操作系統(tǒng)自動(dòng)喚醒。以下方法會(huì)讓線程進(jìn)入限期等待狀態(tài):
- Thread.sleep()方法罩旋;
- 設(shè)置了timeout參數(shù)的Object.wait()方法啊央;
- 設(shè)置了timeout參數(shù)的Thread.join()方法;
- LockSupport.parkNanos()方法涨醋;
- LockSupport.parkUntil()方法瓜饥;
- 阻塞(Blocked):線程被阻塞了,“阻塞狀態(tài)”與“等待狀態(tài)”的區(qū)別是:“阻塞狀態(tài)”在等待著獲取到一個(gè)排它鎖浴骂,這個(gè)事件將在另外一個(gè)線程放棄這個(gè)鎖的時(shí)候發(fā)生乓土;而“等待狀態(tài)”則是在等待一段時(shí)間,或者喚醒動(dòng)作的發(fā)生溯警。在程序等待進(jìn)入同步區(qū)域(synchronized)的時(shí)候趣苏,線程將進(jìn)入這種狀態(tài)。
- 結(jié)束(Terminated):已終止的線程狀態(tài)梯轻,線程已經(jīng)結(jié)束執(zhí)行食磕。
線程間的狀態(tài)轉(zhuǎn)換
1、新建(New)
新創(chuàng)建了一個(gè)線程對(duì)象喳挑,還未調(diào)用start()方法彬伦。
Thread thread = new Thread();
2、就緒(Ready)
線程對(duì)象創(chuàng)建后伊诵,其他線程(比如main線程)調(diào)用了該對(duì)象的start()方法单绑。該狀態(tài)的線程位于可運(yùn)行線程池中,等待被線程調(diào)度選中 獲取cpu 的使用權(quán) 日戈。
3询张、運(yùn)行中(Running)
可運(yùn)行狀態(tài)(runnable)的線程獲得了cpu 時(shí)間片(timeslice) ,執(zhí)行程序代碼浙炼。
4份氧、限期等待(Timed Waiting)
也可以稱作 TIMED_WAITING(有等待時(shí)間的等待狀態(tài))唯袄。
線程主動(dòng)調(diào)用以下方法:
- Thread.sleep方法;
- Object的wait方法蜗帜,帶有時(shí)間恋拷;
- Thread.join方法,帶有時(shí)間厅缺;
- LockSupport的parkNanos方法蔬顾,帶有時(shí)間。
5湘捎、無(wú)限期等待(Waiting)
運(yùn)行中(Running)的線程執(zhí)行了以下方法:
- Object的wait方法诀豁,并且沒(méi)有使用timeout參數(shù);
- Thread的join方法,沒(méi)有使用timeout參數(shù)窥妇;
- LockSupport的park方法舷胜;
- Conditon的await方法。
6活翩、阻塞(Blocked)
阻塞狀態(tài)是指線程因?yàn)槟撤N原因放棄了cpu 使用權(quán)烹骨,暫時(shí)停止運(yùn)行。直到線程進(jìn)入可運(yùn)行(runnable)狀態(tài)材泄,才有機(jī)會(huì)再次獲得cpu timeslice 轉(zhuǎn)到運(yùn)行(running)狀態(tài)沮焕。阻塞的情況分兩種:
- 同步阻塞:運(yùn)行(running)的線程進(jìn)入了一個(gè)synchronized方法,若該同步鎖被別的線程占用拉宗,則JVM會(huì)把該線程放入鎖池(lock pool)中峦树。
- 其他阻塞:運(yùn)行(running)的線程發(fā)出了I/O請(qǐng)求時(shí),JVM會(huì)把該線程置為阻塞狀態(tài)簿废。當(dāng)I/O處理完畢時(shí)空入,線程重新轉(zhuǎn)入可運(yùn)行(runnable)狀態(tài)。
7族檬、結(jié)束(Terminated)
線程run()歪赢、main() 方法執(zhí)行結(jié)束,或者因異常退出了run()方法单料,則該線程結(jié)束生命周期埋凯。