在单线程环境下,线程的生命周期就是“创建、执行和终止”,但是在多线程环境下就不能这么分了。
Java的线程有6种基本的方式,如下:
New:初始状态,线程被构建,但是还没有调用start()方法。
Runnable:运行状态,Java线程将操作系统的就绪和运行两种状态笼统的地称作“运行中”。
Blocked:阻塞状态,当线程执行了synchronized代码,并且没有抢到锁时就会变成该状态。
WAITING:等待状态,表示线程进入等待状态,进入该状态表示当前线程需要等待其他线程通知或者中断。
TIME_WAITING:超时等待状态,该状态与WAITING是不同的,该状态可以再指定的时间自行返回。
TERMINED:终止状态,表示当前线程已经执行完毕、
在这个过程中,Blocked和waing什么区别呢?导致blocked只有一种情况,就是锁等待(Synchronized),这两者没有本质的区别,理解为定义或者发生的背景不一样就行了。
这几种状态之间的转换关系是:

上图中lockSupport用来创建lock锁的基本线程阻塞单元。LockSupport提供的是一个许可,如果存在许可,线程在调用park的时候会立马返回,此时许可会立马被消费掉,如果没有许可,则会阻塞。
下面我们使用多个例子来进一步演示几种状态。
阻塞状态是一种特殊的状态,WAITING,TIME_WAITING,BLOCKED都属于阻塞状态,IO也会引起阻塞状态。 阻塞状态也不止一种情况,有waiting,time_waiting,blocked,io阻塞等 。我们现在就用多个例子来演示一下。
TIME_WAITING状态
- public class TimedWaitingStatusExample {
- public static void main(String[] args) {
- new Thread(() -> {
- try {
- TimeUnit.SECONDS.sleep(10000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }, "TIME_WAITING").start();
- }
- }
运行之后 ,我们使用jstack看一下堆信息,其中有如下一段内容:

这里,我们可以看到线程的状态就是TIMED_WAITING状态,也就是sleeping状态。
WAITING状态
- public class WaitingStatusExample {
- public static void main(String[] args) {
- new Thread(()->{
- synchronized (WaitingStatusExample.class){
- try {
- WaitingStatusExample.class.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },"WAITING").start();
- }
- }
我们同样使用jstack看一下其状态:

我们可以看到WAITING和TIME_WAITING是不一样的,TIME_WAITING就是在sleep,而WAITING则是一致在等待资源(on object monitor)。
Blocked状态
我们再看Blocked状态的例子:
- public class BlockedStatusExample implements Runnable {
- public static void main(String[] args) {
- new Thread(new BlockedStatusExample(), "BLOCKED_T1").start();
- new Thread(new BlockedStatusExample(), "BLOCKED_T2").start();
- }
-
- @Override
- public void run() {
- synchronized (BlockedStatusExample.class) {
- //一直不释放锁
- while (true) {
- }
- }
- }
- }
此时使用jstack查看进程的状态为:

此时我们可以看到BLOCKED_T1抢到了资源,状态为Runnable,而BLOCKED_T2没有抢到锁,状态为监听状态。
而且对比发现BLOCKED_T2的监听状态与上面WAITING的状态基本一致的,这就说明两种状态本质上是一致的,只不过触发的条件不一样罢了。
结论就是:TimeWaiting状态就是sleep状态,会释放占有的资源。而waiting和Blocked状态不仅不释放已经占有的资源,还在等待其他资源。