说说线程的生命周期和状态?
线程生命周期
线程的生命周期是指从创建到销毁的过程,Java 中线程经历以下状态:
1. 新建(New):线程对象创建,未启动。
2. 就绪(Runnable):调用 start()
后,可运行但未分配 CPU。
3. 运行(Running):获得 CPU 执行 run()
。
4. 阻塞(Blocked):等待锁或资源。
5. 等待(Waiting):等待其他线程唤醒。
6. 超时等待(Timed Waiting):等待指定时间。
7. 终止(Terminated):执行完成或异常退出。
状态转换
- 通过方法(如
start()
、sleep()
)或条件(如锁竞争)切换。
1. 线程状态详解
(1) 新建(New)
- 描述:
- 创建
Thread
对象,未调用start()
。 - 示例:
Thread t = new Thread(() -> System.out.println("Run"));
- 特点:
- 未分配线程资源。
(2) 就绪(Runnable)
- 描述:
- 调用
start()
,进入可运行状态,等待 CPU 调度。 - 示例:
t.start();
- 特点:
- 可立即运行或等待调度。
(3) 运行(Running)
- 描述:
- CPU 执行
run()
方法。 - 特点:
- Java API 无此状态(归为
Runnable
),概念上存在。
(4) 阻塞(Blocked)
- 描述:
- 线程尝试获取锁但被占用,进入阻塞队列。
- 示例:
synchronized (obj) { // obj 被其他线程锁住
System.out.println("Locked");
}
- 特点:
- 等待锁释放。
(5) 等待(Waiting)
- 描述:
- 调用
wait()
、join()
等,等待其他线程唤醒。 - 示例:
synchronized (obj) {
obj.wait(); // 进入等待
}
- 特点:
- 无时间限制,需
notify()
。
(6) 超时等待(Timed Waiting)
- 描述:
- 调用带时间的等待方法(如
sleep()
、wait(timeout)
)。 - 示例:
Thread.sleep(1000); // 休眠 1 秒
- 特点:
- 超时自动唤醒。
(7) 终止(Terminated)
- 描述:
run()
执行完或异常退出。- 示例:
Thread t = new Thread(() -> {});
t.start(); // 执行完终止
- 特点:
- 不可重启。
2. 状态转换图
新建(New) --start()--> 就绪(Runnable) --CPU调度--> 运行(Running)
^ | |
| v v
终止(Terminated) <-- sleep()/wait() --> 阻塞/等待(Blocked/Waiting/Timed Waiting)
转换方法
start()
:New -> Runnable。yield()
:Running -> Runnable(让出 CPU)。sleep()
:Running -> Timed Waiting。wait()
:Running -> Waiting。notify()
:Waiting -> Runnable。synchronized
:Running -> Blocked(锁竞争)。
3. 查看状态
- 方法:
Thread.getState()
返回Thread.State
枚举。- 示例:
Thread t = new Thread(() -> {
try { Thread.sleep(1000); } catch (Exception e) {}
});
System.out.println(t.getState()); // NEW
t.start();
Thread.sleep(100); // 等待启动
System.out.println(t.getState()); // TIMED_WAITING
Thread.State 枚举
NEW
RUNNABLE
(包含 Running)BLOCKED
WAITING
TIMED_WAITING
TERMINATED
4. 延伸与面试角度
- 与 OS 线程:
- Java 线程状态映射到操作系统线程。
- 实际应用:
- Blocked:锁竞争(如数据库连接)。
- Waiting:线程同步(如生产者-消费者)。
- Timed Waiting:定时任务。
- 注意事项:
interrupt()
可打断 Waiting/Timed Waiting。- 终止状态不可恢复。
- 面试点:
- 问“状态”时,提 6 种及转换。
- 问“例子”时,写
sleep
或wait
。
总结
线程生命周期包括新建、就绪、运行、阻塞、等待、超时等待和终止 7 种状态,通过方法和条件转换。理解状态有助于调试和优化并发程序。面试时,可画状态图或提 wait()
示例,展示理解深度。