Java 中线程的基本状态
Java 线程状态简介
Java 语言中,线程共有六种状态,分别简介如下:
NEW
:线程已经创建,未调用 start 方法RUNNABLE
:运行状态,该状态包括线程的就绪、运行两个状态BLOCKED
:阻塞状态,通常线程在等待锁的过程为该状态WAITING
:等待状态,当前线程需要等待其他线程作出通知或中断TIME_WAITING
:超时等待状态,其与 WAITING 状态不同点为超时等待可在一段时间后自行返回TERMINATED
:终止状态,当前线程已经执行完毕
Java线程状态转换关系图如下图:
由线程状态转换图中可以很清晰的看出Java语言中线程状态的转换关系,下面展示一个示例,该示例主要是通过构造线程并模拟出线程当前的状态。具体代码及查看如下。
Java线程状态实探
从一个实例谈起
|
|
运行上述代码,我们可以通过 Java 自带的小工具 jstack 查看线程信息。具体操作如下:
- 打开 commond,输入 jps 命令,查看全部 Java 线程的 pid,如下图:
由图中可以看出,当前系统中有三个 Java 进程在运行,我们要查看的便是 pid 为 17628 的 ThreadStatus 进程。 - 输入 jstack [pid],查看进程信息,如下图:
- 分析线程信息。
查看 jstack 输出的信息,我们可以找到我们在程序中启动的四个进程,如下图:
由图中信息可以看出:
- Blocked Thread 线程当前为
BLOCKED
状态,正在等待获取 Blocked.class 对象的锁; - GetLock Thread 线程当前为
TIMED_WAITING
状态,这是因为它获取到了 Blocked.class 对象的锁,并通过 sleep() 进入了超时等待状态; - Waiting Thread 线程当前为
WAITING
状态,这是因为它获取到了自身对象的锁,并通过 wait() 方法进入了等待状态; - TimeWaiting Thread 线程当前为
TIMED_WAITING
状态,其并未获得任何锁,仅是通过 TimeUnit.SECONDS.sleep() 方法使得当前线程进入超时等待状态。
再看示例程序
TimeWaiting
|
|
TimeWaiting 类的定义中,未获得任何对象的锁,仅是通过 TimeUnit.SECONDS.sleep() 方法使得当前线程进入 超时等待 状态。
注:此处 TimeUnit.SECONDS.sleep() 方法与 Thread.sleep() 方法使用类似。但在可读性上,TimeUnit.SECONDS.sleep() 方法更优。
Waiting
|
|
Waiting 类的定义中,我们通过 Object.wait() 方法使得线程进入等待状态。此处获取对象锁的原因是由于 Java 语言中,当某个线程试图等待一个自己并不拥有的对象(O)的监控器或者通知其他线程等待该对象(O)的监控器时,会抛出 java.lang.IllegalMonitorStateException
异常。
调用 wait() 方法后,当前线程状态便变成了 等待 状态。
Blocked
|
|
Blocked 类的定义中,首先该线程需要获取 Blocked.class 对象的对象锁,然后对当前线程执行 sleep,进入超时等待。
主方法中,我们创建了两个任务为 Blocked 的线程,由于第一个线程首先会获取 Blocked.class 对象的对象锁,然后进入等待状态(不释放锁),所以 GetLock Thread 会在获取锁的状态下,进入等待状态;而 Blocked Thread 则会由于等待 Blocked.class 对象的对象锁而进入 阻塞状态。
总结
本文仅是一篇真对 Java 线程的基本介绍,针对 Thread 类源码分析以及常见方法的使用,将在日后的文章中有所介绍。由于初学且行文时间较赶,如果错误多多指教。有相关讨论可以联系 Email:JaydenRansom@outlook.com