【多线程】Thread 类中线程的状态

目录

一、再谈线程状态

二、线程状态的作用


一、再谈线程状态

之前我们说到,操作系统的线程有两种比较常见的状态------就绪状态 和 阻塞状态。

Java 为了能够调度操作系统的线程重新封装了一个专门用于管理线程调度的 Thread 类,同时也给线程的状态重新封装。

以下是重新封装后的线程状态:

线程状态 说明
NEW(初始状态) 新建了一个 Thread 类对象,但是还未调用 start 方法,操作系统层面的线程还未正式被创建
RUNNABLE(就绪状态 / 运行状态) 新建 Thread 类对象之后调用了 start 方法,该线程处于就绪状态或者运行状态
BLOCKED(阻塞状态) 线程此时因为锁而阻塞
WAITING(等待状态) 线程处于等待状态,若未被其他线程显式唤醒将会无限等待
TIMED_WAITING(超时等待) 线程处于限时的等待状态,当等待的时间超过了限定的时间,线程将会停止等待并继续执行
TERMINATED(终止状态) 当线程的 run () 方法执行完成或者主线程执行完成时,线程处于终止状态。线程一旦终止就不可再生

在 IDEA 中查看线程的状态:

java 复制代码
public class Demo13_threadState {
    // 查看 Thread 类所有的线程状态
    public static void main1(String[] args) {
        for (Thread.State state : Thread.State.values()) {
            System.out.println(state);
        }
    }

    // NEW 状态
    public static void main2(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while (true) {
                // 什么都不做
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        System.out.println(t.getState());
    }

    // RUNNABLE 状态
    public static void main3(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while (true) {
                // 什么都不做
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();

        System.out.println(t.getState());
    }

    // TIMED_WAITING 状态
    public static void main4(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while (true) {
                // 什么都不做
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();

        Thread.sleep(1000);
        System.out.println(t.getState());
    }
}

当我们运行 main4 的时候,可以使用 jconsole 程序来查看当前程序中线程的状态:

二、线程状态的作用

小编认为,理解线程状态 并 懂得查看和分析线程状态 是调试多线程程序的重要技能之一。

如果在业务中发现代码的某个逻辑出 bug 了,我们就可以观察线程的状态从而分析是哪里出问题了:

  1. 当程序出现 bug ,我们可以借助第三方工具如 jconsole 来查看当前程序中对应逻辑线程的状态;

  2. 根据线程的状态来分析出 bug 的可能性:

如果线程的状态是 TIMED_WAITING 或者 WAITING,就得考虑一下是不是代码中某个方法产生了线程等待且没有及时将线程显式唤醒;

如果线程的状态是 BLOCKED,就得考虑一下代码中是不是出现了死锁;

如果线程的状态是 RUNNABLE,那说明线程本身没有问题,就得考虑一下是不是代码中的某些逻辑条件没有按预期触发。

......

  1. 再看看线程的调用栈,找到出现问题的具体代码行。

然后就找出问题所在:原来程序是因为循环 sleep 导致的等待啊!

那么本文到此就先告一段落啦~


相关推荐
程序员清风25 分钟前
程序员兼职必看:靠谱软件外包平台挑选指南与避坑清单!
java·后端·面试
皮皮林5512 小时前
利用闲置 Mac 从零部署 OpenClaw 教程 !
java
华仔啊7 小时前
挖到了 1 个 Java 小特性:var,用完就回不去了
java·后端
SimonKing7 小时前
SpringBoot整合秘笈:让Mybatis用上Calcite,实现统一SQL查询
java·后端·程序员
日月云棠1 天前
各版本JDK对比:JDK 25 特性详解
java
用户8307196840821 天前
Spring Boot 项目中日期处理的最佳实践
java·spring boot
JavaGuide1 天前
Claude Opus 4.6 真的用不起了!我换成了国产 M2.5,实测真香!!
java·spring·ai·claude code
IT探险家1 天前
Java 基本数据类型:8 种原始类型 + 数组 + 6 个新手必踩的坑
java
花花无缺1 天前
搞懂new 关键字(构造函数)和 .builder() 模式(建造者模式)创建对象
java
用户908324602731 天前
Spring Boot + MyBatis-Plus 多租户实战:从数据隔离到权限控制的完整方案
java·后端