核心概念

Java线程有6种状态,定义在Thread.State枚举中:

  1. NEW(新建)
  2. RUNNABLE(可运行)
  3. BLOCKED(阻塞)
  4. WAITING(等待)
  5. TIMED_WAITING(超时等待)
  6. TERMINATED(终止)

状态详解与转换

状态转换图

         NEW
          |
        start()
          ↓
      RUNNABLE ←─────────────┐
       ↙  ↓  ↘               │
   BLOCKED WAITING TIMED_WAITING
       ↘  ↓  ↙               │
      RUNNABLE                │
          ↓                   │
      TERMINATED ──────────────┘

1. NEW(新建)

Thread thread = new Thread(() -> {});
// 此时状态为 NEW
System.out.println(thread.getState()); // NEW

特点:线程对象已创建,但尚未调用start()方法。

2. RUNNABLE(可运行)

thread.start();
// 此时状态为 RUNNABLE
System.out.println(thread.getState()); // RUNNABLE

特点

  • 包含操作系统层面的RunningReady两种状态
  • 线程可能正在执行,也可能在等待CPU时间片
  • Java不区分这两种状态,统一为RUNNABLE

进入方式

  • NEW → 调用start()RUNNABLE
  • BLOCKED/WAITING/TIMED_WAITING → 条件满足 → RUNNABLE

3. BLOCKED(阻塞)

synchronized(lock) {
    // 如果锁被占用,当前线程进入BLOCKED状态
}

特点:等待获取synchronized锁(Monitor)

进入方式

  • 尝试进入synchronized代码块/方法,但锁被其他线程持有

退出方式

  • 获取到锁 → RUNNABLE

4. WAITING(无限等待)

// 方式1:Object.wait()
synchronized(lock) {
    lock.wait(); // 进入WAITING,释放锁
}

// 方式2:Thread.join()
thread.join(); // 等待thread线程结束

// 方式3:LockSupport.park()
LockSupport.park(); // 进入WAITING

特点

  • 无限期等待,直到被显式唤醒
  • wait()会释放锁,park()不涉及锁

进入方式

  • Object.wait()(无超时参数)
  • Thread.join()(无超时参数)
  • LockSupport.park()

退出方式

  • Object.notify()/notifyAll()
  • 被等待的线程执行完毕
  • LockSupport.unpark()

5. TIMED_WAITING(超时等待)

// 方式1:Thread.sleep()
Thread.sleep(1000); // 进入TIMED_WAITING,不释放锁

// 方式2:Object.wait(timeout)
synchronized(lock) {
    lock.wait(1000); // 进入TIMED_WAITING,释放锁
}

// 方式3:Thread.join(timeout)
thread.join(1000);

// 方式4:LockSupport.parkNanos()/parkUntil()
LockSupport.parkNanos(1000000000L); // 1秒

特点

  • 有超时时间,到期自动唤醒
  • sleep()不释放锁,wait(timeout)释放锁

退出方式

  • 超时时间到期
  • 被提前唤醒(notify()/unpark()

6. TERMINATED(终止)

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

特点

  • 线程执行结束,生命周期终结
  • 不可重新启动(再次调用start()会抛IllegalThreadStateException

源码关键点

Thread.State源码

public enum State {
    NEW,           // 初始状态
    RUNNABLE,      // 运行状态
    BLOCKED,       // 阻塞状态(等待锁)
    WAITING,       // 等待状态(无限期)
    TIMED_WAITING, // 超时等待
    TERMINATED;    // 终止状态
}

状态检查

public State getState() {
    // 由JVM实现,返回线程当前状态
    return jdk.internal.misc.VM.toThreadState(threadStatus);
}

面试常见陷阱

1. BLOCKED vs WAITING

状态 触发场景 是否释放锁
BLOCKED 等待synchronized 未持有锁
WAITING wait()/join()/park() wait()释放锁

2. sleep() vs wait()

// sleep:TIMED_WAITING,不释放锁
synchronized(lock) {
    Thread.sleep(1000); // 仍持有lock
}

// wait:WAITING,释放锁
synchronized(lock) {
    lock.wait(); // 释放lock,其他线程可进入
}

3. RUNNABLE的双重含义

// RUNNABLE包含两种操作系统状态:
// 1. Ready:在就绪队列,等待CPU调度
// 2. Running:正在CPU上执行
// Java层面无法区分,统一为RUNNABLE

答题总结

面试标准答案

Java线程有6种状态

  1. NEW:创建未启动
  2. RUNNABLE:可运行(含Running和Ready)
  3. BLOCKED:等待synchronized锁
  4. WAITING:无限期等待(wait/join/park)
  5. TIMED_WAITING:超时等待(sleep/wait(timeout))
  6. TERMINATED:执行结束

关键流转

  • NEWstart()RUNNABLE
  • RUNNABLE → 等待锁 → BLOCKED → 获取锁 → RUNNABLE
  • RUNNABLEwait()/park()WAITINGnotify()/unpark()RUNNABLE
  • RUNNABLEsleep()/wait(timeout)TIMED_WAITING → 超时/唤醒 → RUNNABLE
  • RUNNABLE → 执行完毕 → TERMINATED

核心区别

  • BLOCKED是被动等锁,WAITING是主动等待
  • sleep()不释放锁,wait()释放锁
  • RUNNABLE包含操作系统的就绪和运行两种状态