Java中的线程状态与转换机制详解
字数 1331 2025-11-11 09:10:01
Java中的线程状态与转换机制详解
一、线程状态的基本概念
在Java中,线程的生命周期被定义为6种状态,这些状态在Thread.State枚举中明确列出:
- NEW(新建状态)
- RUNNABLE(可运行状态)
- BLOCKED(阻塞状态)
- WAITING(等待状态)
- TIMED_WAITING(计时等待状态)
- TERMINATED(终止状态)
二、详细状态解析与转换过程
- NEW状态
- 描述:线程对象刚被创建,但尚未调用start()方法
- 特征:此时线程还未被系统调度执行
- 示例代码:
Thread thread = new Thread(() -> {});
System.out.println(thread.getState()); // 输出NEW
- NEW → RUNNABLE
- 触发条件:调用线程的start()方法
- 过程:JVM为线程分配系统资源,将其加入就绪队列等待CPU调度
- 注意:不能重复调用start()方法,否则会抛出IllegalThreadStateException
- RUNNABLE状态详解
- 包含两个子状态:就绪(Ready)和运行中(Running)
- 就绪:线程已准备好,等待CPU时间片
- 运行中:线程正在CPU上执行
- 状态判断:无法通过API区分就绪和运行中,都显示为RUNNABLE
- RUNNABLE → BLOCKED
- 触发条件:线程尝试获取一个被其他线程持有的同步锁(synchronized)
- 典型场景:多个线程竞争同一个对象的监视器锁
- 示例:
synchronized (lock) {
// 当线程A持有锁时,线程B尝试进入会进入BLOCKED状态
}
- RUNNABLE → WAITING
- 触发方式:
- 调用Object.wait()方法(需先获得对象锁)
- 调用Thread.join()方法(不带超时参数)
- 调用LockSupport.park()方法
- 特征:无限期等待,需要其他线程显式唤醒
- WAITING → RUNNABLE
- 唤醒方式:
- Object.notify()/notifyAll()(对应wait())
- 被join的线程执行完毕
- LockSupport.unpark(thread)
- RUNNABLE → TIMED_WAITING
- 触发方式(带超时参数):
- Thread.sleep(long millis)
- Object.wait(long timeout)
- Thread.join(long millis)
- LockSupport.parkNanos()/parkUntil()
- 特征:在指定时间后自动唤醒或提前被中断
- 状态转换完整流程图
NEW --start()--> RUNNABLE --获锁失败--> BLOCKED
|
|--执行完毕--> TERMINATED
|
|--wait()/join()--> WAITING
| ↑
|--notify()/interrupt()--
|
|--sleep()/wait(timeout)--> TIMED_WAITING
三、重要注意事项
- 中断机制
- 调用thread.interrupt()可中断WAITING/TIMED_WAITING状态
- 被中断的线程会抛出InterruptedException,并清除中断标志
- 状态监控实战
public class ThreadStateMonitor {
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
Thread thread = new Thread(() -> {
synchronized (lock) {
try {
Thread.sleep(1000); // TIMED_WAITING
lock.wait(); // WAITING
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
System.out.println("创建后:" + thread.getState()); // NEW
thread.start();
Thread.sleep(100); // 确保thread进入同步块
System.out.println("启动后:" + thread.getState()); // TIMED_WAITING或BLOCKED
Thread.sleep(2000);
System.out.println("wait后:" + thread.getState()); // WAITING
}
}
四、常见面试问题分析
- BLOCKED和WAITING的区别?
- BLOCKED:在等待获取监视器锁,是主动的竞争状态
- WAITING:等待其他线程的显式唤醒,是被动的等待状态
- sleep()和wait()的异同?
- 相同点:都会让线程暂停执行
- 不同点:
- sleep()不释放锁,wait()会释放锁
- sleep()是Thread的方法,wait()是Object的方法
- sleep()自动唤醒,wait()需要被唤醒
理解线程状态转换机制对于多线程编程、死锁排查和性能优化都具有重要意义,是Java并发编程的基础核心知识。