【多线程】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 导致的等待啊!

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


相关推荐
云烟成雨TD18 小时前
Spring AI Alibaba 1.x 系列【6】ReactAgent 同步执行 & 流式执行
java·人工智能·spring
于慨18 小时前
Lambda 表达式、方法引用(Method Reference)语法
java·前端·servlet
swg32132118 小时前
Spring Boot 3.X Oauth2 认证服务与资源服务
java·spring boot·后端
gelald18 小时前
SpringBoot - 自动配置原理
java·spring boot·后端
殷紫川18 小时前
深入理解 AQS:从架构到实现,解锁 Java 并发编程的核心密钥
java
一轮弯弯的明月18 小时前
贝尔数求集合划分方案总数
java·笔记·蓝桥杯·学习心得
chenjingming66618 小时前
jmeter线程组设置以及串行和并行设置
java·开发语言·jmeter
殷紫川19 小时前
深入拆解 Java volatile:从内存屏障到无锁编程的实战指南
java
eddieHoo19 小时前
查看 Tomcat 的堆内存参数
java·tomcat
那个失眠的夜19 小时前
Mybatis延迟加载策略
xml·java·数据库·maven·mybatis