线程的 6 个状态(生命周期)

发布时间 2023-05-27 21:55:11作者: Java知者

线程的 6 个状态(生命周期)


1. 线程的一生中有哪几个状态

有6种状态,分别如下:

  • New
  • Runnable
  • Blocked
  • Waiting
  • Timed_Waiting
  • Terminated

2. 每个状态的含义是什么

New:是在 new Thread() 之后,执行 start() 方法之前的一个状态;

Runnable:是在线程调用 start() 方法之后的状态(其实包括两个阶段:一是 start() 方法调用之后但是未拿到 cpu 资源的 ready 阶段,二是拿到cpu资源的后的 Running 阶段);

Blocked:进入到 synchronized 修饰的相关方法或者代码块,但是没有拿到锁;等拿到 monitor 锁之后会重新进入 Runnable 状态;

Waiting:执行了 wait() 等方法后进入的一个状态,可见下图;

Timed_Waiting:执行了带有 time 参数的 wait(time) 方法后的状态,见下图;

Terminated:线程运行的最终状态:可能是run() 方法的逻辑运行结束,也有可能是遇到未被 catch 的异常,抛出异常后终止。

六种状态的含义和相互转换

上图展示了六种状态的含义和相互转换。

3. 代码展示六种状态

(1)展示线程的NEW、RUNNABLE、Terminated状态

/**
 * 描述:     展示线程的NEW、RUNNABLE、Terminated状态。即使是正在运行,也是Runnable状态,而不是Running。
 */
public class NewRunnableTerminated implements Runnable {

    public static void main(String[] args) {
        Thread thread = new Thread(new NewRunnableTerminated());
        //打印出NEW的状态
        System.out.println(thread.getState());
        thread.start();
        // 打印出 RUNNABLE 的状态,执行完 start() 方法就是 RUNNABLE,即使它可能还没有拿到cpu,开始真正的运行
        System.out.println(thread.getState());
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //打印出RUNNABLE的状态,即使是正在运行,也是RUNNABLE,而不是RUNNING
        System.out.println(thread.getState());
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //打印出TERMINATED状态
        System.out.println(thread.getState());
    }

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println(i);
        }
    }
}

打印结果:

NEW
RUNNABLE
0
1
2
3
... 中间的省略掉
710
711
RUNNABLE
712
713
714
715
716
... 中间的省略掉
998
999
TERMINATED

(2) 展示Blocked, Waiting, TimedWaiting

/**
 * 描述:     展示Blocked, Waiting, TimedWaiting
 */
public class BlockedWaitingTimedWaiting implements Runnable{
    public static void main(String[] args) {
        BlockedWaitingTimedWaiting runnable = new BlockedWaitingTimedWaiting();
        Thread thread1 = new Thread(runnable);
        thread1.start();
        Thread thread2 = new Thread(runnable);
        thread2.start();
        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //打印出Timed_Waiting状态,因为正在执行Thread.sleep(1000);
        System.out.println(thread1.getState());
        //打印出BLOCKED状态,因为thread2想拿得到sync()的锁却拿不到
        System.out.println(thread2.getState());
        try {
            Thread.sleep(1300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //打印出WAITING状态,因为执行了wait()
        System.out.println(thread1.getState());

    }

    @Override
    public void run() {
        syn();
    }

    private synchronized void syn() {
        try {
            Thread.sleep(1000);
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

打印结果:

阻塞状态:

一般习惯而言,Blocked(被阻塞),Waiting(等待)、Timed_waiting(计时等待)都被称为阻塞状态。因为他们都需要被线程以外的条件去唤醒,不是当前线程所控制的。

文章来源:线程的 6 个状态(生命周期)

个人微信:CaiBaoDeCai

微信公众号名称:Java知者

微信公众号 ID: JavaZhiZhe

谢谢关注!