线程的5种状态
线程可以有如下5种状态:
5种状态的转换图如下
New (新创建)
当用new操作符创建一个线程时,如new Thread(r),该线程还没有开始运行。这意外这它的状态是new。此时程序还没有开始运行线程中的代码,在线程运行之前还有一些基础工作要做。
Runnable (可运行/就绪)
一旦处于新状态的线程调用start方法(如图中的1所示),线程就处于Runnbale状态。
处于Runnable状态的线程还未运行run()方法的代码,只有在获得CPU时间片才开始运行。
Running (运行中)
当线程获得CPU时间片,线程就进入Running状态(如图中的2所示)。
处于Running状态的线程有可能在运行中CPU时间片用完,而run方法没运行完,线程就又进入Runnable状态。
通常情况下,运行中的线程一直处于Running与Runnable交替转换的过程中。
Blocked (等待/阻塞/睡眠)
当线程在Running状态中,遇到阻塞等待锁、等待用户输入、调用sleep()方法、调用join等待其他线程情况,会导致线程进入阻塞状态(Blocked)。
处于阻塞状态的线程,在阻塞等待结束之后,会进入Runnable状态,等等获得CPU时间片继续运行程序。
Dead (死亡)
当线程运行完run方法,直接进入死亡状态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);
}
查看线程正在执行的代码
在程序运行的过程中,可以基于jstack查看线程正在执行的堆栈信息,示例:
jstack 10765 | grep ‘0x2a34’ -C5 --color
其中,'10765'是进程id,'0x2a34'是16进制的线程id
参考文献
1、《Java核心技术 卷I》
2、《线上服务CPU100%问题快速定位实战》