1.背景
编写多线程相关的程序,必然会用到线程状态的相关知识点,
那么这篇博客就给大家系统的分析一下多线程的状态,
由于java中线程状态与操作系统中的线程状态划分有区别,
因此这里优先介绍操作系统的5种线程状态
2.操作系统给线程划分的5种状态
状态说明:
状态一:【初始状态】仅是在语言层面创建了线程对象,还未与操作系统线程关联
状态二:【可运行状态(就绪状态)】指该线程已经被创建(与操作系统线程关联),可以由 CPU 调度执行
状态三:【运行状态】指获取了 CPU 时间片运行中的状态当 CPU 时间片用完,会从【运行状态】转换至【可运行状态】,会导致线程的上下文切换,因此并不是线程越多越好.
状态四:【阻塞状态】如果调用了阻塞 API,如 BIO 读写文件,这时该线程实际不会用到 CPU,会导致线程上下文切换,进入【阻塞状态】等 BIO 操作完毕,会由操作系统唤醒阻塞的线程,转换至【可运行状态】与【可运行状态】的区别是,对【阻塞状态】的线程来说只要它们一直不唤醒,调度器就一直不会考虑调度它们
状态五:【终止状态】表示线程已经执行完毕,生命周期已经结束,不会再转换为其它状态
3.java中给线程划分的6中状态
java中规定线程有6中状态
源码: Thread.State 中,如下:
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }
状态说明:
NEW: 线程刚被创建,但是还没有调用 start() 方法
RUNNABLE:当调用了 start() 方法之后,注意,Java API 层面的 RUNNABLE 状态涵盖了 操作系统 层面的【可运行状态】、【运行状态】和【阻塞状态】(由于 BIO 导致的线程阻塞,在 Java 里无法区分,仍然认为是可运行)
BLOCKED 、WAITING 、TIMED_WAITING : 都是 Java API 层面对【阻塞状态】的细分,请看下面的状态案例演示。
TERMINATED:当线程代码运行结束
4.代码演示java中的5种状态
package com.ldp.demo01; import com.common.MyThreadUtil; import lombok.extern.slf4j.Slf4j; /** * @author 姿势帝-博客园 * @address https://www.cnblogs.com/newAndHui/ * @WeChat 851298348 * @create 01/16 6:38 * @description */ @Slf4j public class ThreadStateTest { /** * java 中线程的6中状态演示 * * @param args */ public static void main(String[] args) { // 演示 NEW 状态 Thread thread1 = new Thread(() -> { }, "thread1"); // 演示 RUNNABLE 状态 Thread thread2 = new Thread(() -> { while (true) { } }, "thread2"); thread2.start(); // 演示 TERMINATED 状态 Thread thread3 = new Thread(() -> { log.debug("running........"); }, "thread3"); thread3.start(); // 演示 TIMED_WAITING 状态 Thread thread4 = new Thread(() -> { synchronized (ThreadStateTest.class) { MyThreadUtil.sleep(10000); } }, "thread4"); thread4.start(); // 演示 WAITING 状态 Thread thread5 = new Thread(() -> { try { thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } }, "thread5"); thread5.start(); // 演示 BLOCKED 状态 Thread thread6 = new Thread(() -> { synchronized (ThreadStateTest.class) { MyThreadUtil.sleep(10000); } }, "thread6"); thread6.start(); // 等2秒 后查看状态 MyThreadUtil.sleep(2); log.debug("thread1 state = {}", thread1.getState()); // NEW log.debug("thread2 state = {}", thread2.getState()); // RUNNABLE log.debug("thread3 state = {}", thread3.getState()); // TERMINATED log.debug("thread4 state = {}", thread4.getState()); // TIMED_WAITING log.debug("thread5 state = {}", thread5.getState()); // WAITING log.debug("thread6 state = {}", thread6.getState()); // BLOCKED } }
测试结果:
21:08:29 [thread3] DEBUG com.ldp.demo01.ThreadStateTest.33 -> running........
21:08:31 [main] DEBUG com.ldp.demo01.ThreadStateTest.65 -> thread1 state = NEW
21:08:31 [main] DEBUG com.ldp.demo01.ThreadStateTest.66 -> thread2 state = RUNNABLE
21:08:31 [main] DEBUG com.ldp.demo01.ThreadStateTest.67 -> thread3 state = TERMINATED
21:08:31 [main] DEBUG com.ldp.demo01.ThreadStateTest.68 -> thread4 state = TIMED_WAITING
21:08:31 [main] DEBUG com.ldp.demo01.ThreadStateTest.69 -> thread5 state = WAITING
21:08:31 [main] DEBUG com.ldp.demo01.ThreadStateTest.70 -> thread6 state = BLOCKED