Java 线程的几种状态

❣️关注专栏: JavaEE

线程的所有状态

对当前线程调度的情况我们用状态来描述。线程调度的最基本的单位,那么状态更应该是线程的属性。线程的状态是一个枚举类型 Thread.State,里边包含了6个状态。

public class ThreadState {
	public static void main(String[] args) {
		for (Thread.State state : Thread.State.values()) {
			System.out.println(state);
		}
	}
}

在Java中我们对线程的状态进行了细化,主要分为了6个状态。状态如下:

  1. NEW: 安排了工作, 还未开始行动。创建了Thread,但是还没有调用 start (内核还没有创建对应的 PCB)
  2. RUNNABLE: 可工作的. 又可以分成正在工作中和即将开始工作。也是叫做可运行的,分为以下两个情况:
    (1)正在 CPU 上执行的
    (2)在就绪队列中,随时可以去 CPU 上执行
  3. BLOCKED: 表示排队等着其他事情
  4. WAITING: 表示排队等着其他事情
  5. TIMED_WAITING: 表示排队等着其他事情
  6. TERMINATED: 工作完成了。表示内核中的 PCB 已经执行完毕,但是 Thread 对象还在。

其中 3、4、5 都是阻塞,表示线程PCB正在阻塞队列中。
这几个状态都是不同原因的阻塞。

线程的状态切换

状态转移图Java 线程的几种状态_第1张图片

在这里解释一个疑惑:为什么PCB都释放了,线程的对象还在呢?此时线程存在的意义是什么?
  直白来说,此时线程的存在是没有意义的,但是Java里做不到和内核的线程销毁同步释放对象。一旦内核里的线程PCB消亡了,此时代码中的线程的对象就没用了,之所对象还存在着,是因为 Java 中对象的生命周期有它自己的规则,这个生命周期和内核里的线程并非完全一致,内核的线程释放的时候,无法保证Java代码中的线程的对象也立即释放,在这个时候,就需要通过特定的状态把线程的对象标识为“无效”。
  PCB没了,但是对象还在,我们还可以调用对象的方法属性,只是没法通过多线程来做一些操作了。

线程的状态转移

刚开始我们就先来看这4个状态 NEW 、 RUNNABLE 、TIMED_WAITING、 TERMINATED 的转换,后续我们再看其他的状态转移切换。

public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                // 1.这个循环啥都不干,也不 sleep ---> 如果什么都不干,那么在下边 t 执行中的状态:为 RUNNABLE                           
            }
        });

        // 启动之前,获取 t 的状态,就是 new 状态
        System.out.println("start 之前:"+t.getState());
        t.start();      
        // 线程执行完毕之后,就是 TERMINATED 状态
        System.out.println(" t 结束之后:" + t.getState());
    }

代码执行结果:在这里插入图片描述
之所以能够看到 RUNNABLE,是因为当前线程 run 里边没有写 sleep 之类的方法

public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                /* 2.加入 sleep 方法 ---> 此处在后续打印状态中,具体看到的是 RUNNABLE 还是 TIMED_WAITING
                    就不一定了取决于当前 t 线程运行到了哪个环节
                 */
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        // 启动之前,获取 t 的状态,就是 new 状态
        System.out.println("start 之前:"+t.getState());

        t.start();
        /* 通过循环获取,就能看到交替状态了,当前获取的状态是什么,完全取决于系统的调度操作
            获取状态的这一瞬间,到底 t 线程是在什么样的状态(正在执行,还是正在 sleep)
         */
        for (int i = 0; i < 1000; i++) {
            System.out.println(" t 执行中的状态:" + t.getState());
        }
        t.join(); // 此处的 join 就是让当前的 main 线程来等待 t 线程执行结束(等待 t 的 run 执行完)

        // 线程执行完毕之后,就是 TERMINATED 状态
        System.out.println(" t 结束之后:" + t.getState());
    }

运行结果较长,小编就不截图了,还请读者自行运行查看哦!!!
  之前我们学过的 isAlive() 方法,可以认为是处于不是 NEW 和 TERMINATED 的状态都是活着的。

你可能感兴趣的:(JavaEE,java,java-ee)