深入浅出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输出的线程堆栈

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

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

相关推荐
郁大锤18 分钟前
Android Studio 国内镜像使用与 SDK 下载速度优化指南
android·ide·android studio
那就摆吧1 小时前
数据结构-栈
android·java·c语言·数据结构
奔跑吧 android1 小时前
【android bluetooth 框架分析 02】【Module详解 4】【Btaa 模块介绍】
android·bluetooth·bt·aosp13·btaa
tangweiguo030519871 小时前
Android Compose Activity 页面跳转动画详解
android·compose
Yang-Never2 小时前
ADB -> pull指令拉取手机文件到电脑上
android·adb·android studio
Yang-Never2 小时前
ADB -> pull指令推送电脑文件到手机上
android·adb·android studio
李新_2 小时前
我们封装了哪些好用的Flutter Mixin
android·flutter
帅次2 小时前
Flutter Expanded 与 Flexible 详解
android·flutter·ios·小程序·webview
流浪汉kylin2 小时前
Android手机如何腾出存储空间
android
0wioiw03 小时前
Kotlin基础(①)
android·开发语言·kotlin