線程的5種狀態(tài)
線程可以有如下5種狀態(tài):
5種狀態(tài)的轉換圖如下
New (新創(chuàng)建)
當用new操作符創(chuàng)建一個線程時,如new Thread(r)绅喉,該線程還沒有開始運行。這意外這它的狀態(tài)是new瓢省。此時程序還沒有開始運行線程中的代碼叉抡,在線程運行之前還有一些基礎工作要做。
Runnable (可運行/就緒)
一旦處于新狀態(tài)的線程調(diào)用start方法(如圖中的1所示)角撞,線程就處于Runnbale狀態(tài)呛伴。
處于Runnable狀態(tài)的線程還未運行run()方法的代碼,只有在獲得CPU時間片才開始運行谒所。
Running (運行中)
當線程獲得CPU時間片热康,線程就進入Running狀態(tài)(如圖中的2所示)。
處于Running狀態(tài)的線程有可能在運行中CPU時間片用完劣领,而run方法沒運行完姐军,線程就又進入Runnable狀態(tài)。
通常情況下尖淘,運行中的線程一直處于Running與Runnable交替轉換的過程中奕锌。
Blocked (等待/阻塞/睡眠)
當線程在Running狀態(tài)中,遇到阻塞等待鎖村生、等待用戶輸入惊暴、調(diào)用sleep()方法、調(diào)用join等待其他線程情況趁桃,會導致線程進入阻塞狀態(tài)(Blocked)辽话。
處于阻塞狀態(tài)的線程,在阻塞等待結束之后镇辉,會進入Runnable狀態(tài)屡穗,等等獲得CPU時間片繼續(xù)運行程序。
Dead (死亡)
當線程運行完run方法忽肛,直接進入死亡狀態(tài)Dead 。
代碼中獲得線程信息
在程序運行中烂斋,在代碼中打印線程的信息(線程id,hashCode,name,id,priority,state等)屹逛,方法如下:
public static String getCurrentThreadInfo(){
Thread current = Thread.currentThread();
Map<String,Object> threadInfoMap = new HashMap<>();
threadInfoMap.put("hashCode",current.hashCode());
threadInfoMap.put("name",current.getName());
threadInfoMap.put("id",current.getId());
threadInfoMap.put("priority",current.getPriority());
threadInfoMap.put("state",current.getState());
return JSON.toJSONString(threadInfoMap);
}
查看線程正在執(zhí)行的代碼
在程序運行的過程中础废,可以基于jstack查看線程正在執(zhí)行的堆棧信息,示例:
jstack 10765 | grep ‘0x2a34’ -C5 --color
其中罕模,'10765'是進程id,'0x2a34'是16進制的線程id
參考文獻
1评腺、《Java核心技術 卷I》
2、《線上服務CPU100%問題快速定位實戰(zhàn)》