深入浅出Java线程状态

在Java中,线程的状态 是通过Thread.State枚举明确定义的,共分为6种状态。理解这些状态及其转换关系是掌握多线程编程的基础。下面我会结合源码、流程图和实际代码示例,帮你彻底理清线程的生命周期。


一、Java线程的6种状态(Thread.State枚举)

java 复制代码
public enum State {
    NEW,          // 线程刚创建,未启动
    RUNNABLE,     // 可运行状态(可能在运行或等待CPU调度)
    BLOCKED,      // 被阻塞(等待监视器锁)
    WAITING,      // 无限期等待(直到被显式唤醒)
    TIMED_WAITING, // 有限期等待(自动唤醒)
    TERMINATED    // 线程已终止
}

二、详细状态解析与转换流程图

状态转换图:

stateDiagram-v2 [*] --> NEW NEW --> RUNNABLE: start() RUNNABLE --> BLOCKED: 竞争锁失败 BLOCKED --> RUNNABLE: 获取到锁 RUNNABLE --> WAITING: wait()/join()/park() WAITING --> RUNNABLE: notify()/unpark() RUNNABLE --> TIMED_WAITING: sleep(ms)/wait(ms) TIMED_WAITING --> RUNNABLE: 超时/notify() RUNNABLE --> TERMINATED: run()执行完毕

状态详解:

  1. NEW(新建)

    • 线程对象已创建但未调用start()

    • 示例:

      java 复制代码
      Thread thread = new Thread(() -> {});
      System.out.println(thread.getState()); // 输出 NEW
  2. RUNNABLE(可运行)

    • 包含两种子状态:
      • Ready:等待CPU调度(线程在就绪队列中)
      • Running:正在执行(占用CPU)
    • 触发条件:调用start()后进入该状态
    • 注意:IO阻塞(如Socket读写)不会改变状态,仍为RUNNABLE
  3. BLOCKED(阻塞)

    • 线程未能获取synchronized锁时的状态

    • 示例:

      java 复制代码
      synchronized (lock) {
          // 其他线程尝试进入时会阻塞
      }
  4. WAITING(无限等待)

    • 需要被其他线程显式唤醒

    • 触发方法:

      • Object.wait()(需配合notify())
      • Thread.join()(等待目标线程终止)
      • LockSupport.park()
    • 示例:

      java 复制代码
      synchronized (lock) {
          lock.wait(); // 进入WAITING
      }
  5. TIMED_WAITING(超时等待)

    • 带时间限制的等待,超时后自动唤醒

    • 触发方法:

      • Thread.sleep(long ms)
      • Object.wait(long timeout)
      • LockSupport.parkNanos()
    • 示例:

      java 复制代码
      Thread.sleep(1000); // 进入TIMED_WAITING
  6. TERMINATED(终止)

    • 线程执行完run()方法或抛出未捕获异常

    • 示例:

      java 复制代码
      thread.start();
      thread.join();
      System.out.println(thread.getState()); // 输出 TERMINATED

三、关键状态转换的代码验证

java 复制代码
public class ThreadStateDemo {
    public static void main(String[] args) throws Exception {
        Object lock = new Object();
        
        Thread t1 = new Thread(() -> {
            synchronized (lock) {
                try {
                    lock.wait(1000); // TIMED_WAITING
                } catch (InterruptedException e) {}
            }
        });

        Thread t2 = new Thread(() -> {
            synchronized (lock) {
                try {
                    Thread.sleep(Long.MAX_VALUE); // TIMED_WAITING
                } catch (InterruptedException e) {}
            }
        });

        Thread t3 = new Thread(() -> {
            synchronized (lock) {
                // 竞争锁失败会BLOCKED
            }
        });

        System.out.println("t1: " + t1.getState()); // NEW
        
        t1.start();
        t2.start();
        Thread.sleep(50); // 确保t1/t2进入同步块
        System.out.println("t1: " + t1.getState()); // TIMED_WAITING (wait(1000))
        System.out.println("t2: " + t2.getState()); // TIMED_WAITING (sleep)
        
        t3.start();
        Thread.sleep(50); // 确保t3开始竞争锁
        System.out.println("t3: " + t3.getState()); // BLOCKED
        
        synchronized (lock) {
            lock.notifyAll(); // 唤醒t1
        }
        Thread.sleep(50);
        System.out.println("t1: " + t1.getState()); // TERMINATED
    }
}

四、WAITING vs BLOCKED 的本质区别

状态 触发条件 唤醒方式 典型场景
BLOCKED 竞争synchronized锁失败 锁释放时系统自动分配 多线程竞争同步锁
WAITING 主动调用等待方法 需其他线程显式唤醒 线程间协作(生产者消费者)

五、高频面试题深度解析

  1. sleep()wait()的区别?

    • sleep()是Thread的静态方法,不释放锁,进入TIMED_WAITING;
    • wait()是Object的方法,释放锁,需在同步块中调用。
  2. 如何强制终止线程?

    • 已废弃:Thread.stop()(会导致资源未释放)
    • 正确做法:通过interrupt()中断 + 线程内检查标志位
  3. RUNNABLE状态是否一定在运行?

    • 不一定!可能是就绪状态(等待CPU时间片),可用jstack工具查看实际运行状态。

掌握这些状态转换关系后,你就能:

✅ 精准分析jstack输出的线程堆栈

✅ 设计合理的线程协作逻辑

✅ 快速定位死锁/线程泄漏问题

相关推荐
REDcker35 分钟前
Android WebView 版本升级方案详解
android·音视频·实时音视频·webview·js·编解码
麦兜*37 分钟前
【springboot】图文详解Spring Boot自动配置原理:为什么@SpringBootApplication是核心?
android·java·spring boot·spring·spring cloud·tomcat
le1616161 小时前
Android 依赖种类及区别:远程仓库依赖、打包依赖、模块依赖、本地仓库依赖
android
lxysbly1 小时前
psp模拟器安卓版带金手指
android
云上凯歌2 小时前
02 Spring Boot企业级配置详解
android·spring boot·后端
hqiangtai2 小时前
Android 高级专家技术能力图谱
android·职场和发展
aqi002 小时前
FFmpeg开发笔记(九十七)国产的开源视频剪辑工具AndroidVideoEditor
android·ffmpeg·音视频·直播·流媒体
stevenzqzq2 小时前
Android Koin 注入入门教程
android·kotlin
炼金术3 小时前
SkyPlayer v1.1.0 - 在线视频播放功能更新
android·ffmpeg
用户276038157813 小时前
鲲鹏+昇腾:开启 AI for Science 新范式——基于PINN的流体仿真加速实践
android