一、线程状态概览
Java 线程的状态由 Thread.State 枚举定义:
- 新建(New) :线程对象创建但未调用
start()。 - 就绪(Runnable):线程已启动,等待 CPU 调度。
- 运行(Running) :线程正在执行
run()方法。 - 阻塞(Blocked):线程因等待锁而暂停。
- 等待(Waiting):线程等待其他线程的通知,无限期暂停。
- 超时等待(Timed Waiting):线程在指定时间内等待。
- 终止(Terminated):线程执行完成或异常退出。
线程状态的转换由 JVM 线程调度器和程序员调用的 API 共同控制。下面我们分 Thread 和 Object 类整理相关方法。
二、Thread 类中的线程相关方法
1. Thread.start()
-
作用:启动线程,使其从"新建"进入"就绪"状态。
-
状态转换 :
New -> Runnable -
注意 :只能调用一次,重复调用抛出
IllegalThreadStateException。 -
示例 :
javaThread t = new Thread(() -> System.out.println("Thread running")); t.start(); // New -> Runnable
2. Thread.sleep(long millis)
-
作用:使当前线程暂停指定毫秒数,不释放锁。
-
状态转换 :
Running -> Timed Waiting -
示例 :
javaThread.sleep(1000); // 暂停 1 秒,Running -> Timed Waiting
3. Thread.join()
-
作用:调用线程等待目标线程完成。
-
状态转换 :
Running -> Waiting(若目标线程未结束) -
变体 :
join(long millis):最多等待指定毫秒,Running -> Timed Waiting。
-
示例 :
javaThread t = new Thread(() -> { try { Thread.sleep(2000); } catch (Exception e) {} }); t.start(); t.join(); // 主线程等待 t 结束
4. Thread.interrupt()
-
作用 :中断线程,可能导致
InterruptedException。 -
状态转换 :若线程在
sleep、wait或join中,状态可能提前结束。 -
示例 :
javaThread t = new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Interrupted"); } }); t.start(); t.interrupt();
5. Thread.getState()
-
作用:查询线程当前状态,不改变状态。
-
返回值 :
Thread.State枚举。 -
示例 :
javaThread t = new Thread(() -> {}); System.out.println(t.getState()); // NEW t.start(); System.out.println(t.getState()); // RUNNABLE
6. Thread.stop()(已废弃)
- 作用:强制停止线程。
- 状态转换 :直接进入
Terminated。 - 注意:不安全,已废弃,不推荐使用。
三、Object 类中的线程相关方法
Object 类的以下方法用于线程间的同步和通信,必须在 synchronized 块中使用。
1. Object.wait()
-
作用 :使当前线程等待,直到被
notify()或notifyAll()唤醒,释放锁。 -
状态转换 :
Running -> Waiting -
示例 :
javaObject lock = new Object(); synchronized (lock) { lock.wait(); // Running -> Waiting }
2. Object.wait(long timeout)
-
作用:等待指定时间,超时后自动唤醒。
-
状态转换 :
Running -> Timed Waiting -
示例 :
javasynchronized (lock) { lock.wait(1000); // Running -> Timed Waiting }
3. Object.notify()
-
作用:唤醒一个在该对象上等待的线程。
-
状态转换 :
Waiting -> Runnable -
示例 :
javasynchronized (lock) { lock.notify(); // 唤醒一个等待线程 }
4. Object.notifyAll()
-
作用:唤醒所有在该对象上等待的线程。
-
状态转换 :
Waiting -> Runnable(所有等待线程) -
示例 :
javasynchronized (lock) { lock.notifyAll(); // 唤醒所有等待线程 }
四、线程状态转换全景
以下是线程状态的完整转换路径及触发条件:
-
New -> Runnable- 方法:
Thread.start() - 描述:线程启动,进入就绪队列。
- 方法:
-
Runnable -> Running- 方法:无(JVM 调度器控制)
- 描述:线程被调度,获得 CPU 时间。
-
Running -> Timed Waiting- 方法:
Thread.sleep()、Object.wait(timeout)、Thread.join(timeout) - 描述:线程暂停一段时间。
- 方法:
-
Running -> Waiting- 方法:
Object.wait()、Thread.join() - 描述:线程无限期等待其他线程通知。
- 方法:
-
Running -> Blocked- 方法:无(锁竞争)
- 描述:线程尝试获取已被占用的锁。
-
Waiting/Timed Waiting -> Runnable- 方法:
Object.notify()、Object.notifyAll()、超时结束 - 描述:线程被唤醒或超时,返回就绪状态。
- 方法:
-
Blocked -> Runnable- 方法:无(锁释放)
- 描述:其他线程释放锁。
-
Running -> Terminated- 方法:自然结束、
Thread.interrupt() - 描述:线程执行完成或被中断。
- 方法:自然结束、
五、综合示例
以下代码展示线程状态的常见转换:
java
public class ThreadStateDemo {
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
Thread t1 = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("t1: Running");
lock.wait(); // Running -> Waiting
System.out.println("t1: Resumed");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
System.out.println("t1 state: " + t1.getState()); // NEW
t1.start();
Thread.sleep(100); // 确保 t1 进入 wait
System.out.println("t1 state: " + t1.getState()); // WAITING
synchronized (lock) {
lock.notify(); // Waiting -> Runnable
}
t1.join(); // 主线程等待 t1 结束
System.out.println("t1 state: " + t1.getState()); // TERMINATED
}
}
输出:
yaml
t1 state: NEW
t1: Running
t1 state: WAITING
t1: Resumed
t1 state: TERMINATED
六、总结
Thread类 提供了线程的启动 (start)、暂停 (sleep)、等待 (join) 和中断 (interrupt) 等功能。Object类 提供了线程间通信的机制 (wait、notify、notifyAll),依赖同步锁。- 线程状态转换既有程序员显式控制的部分(如
start、wait),也有 JVM 自动管理的部分(如Runnable -> Running)。
掌握这些方法和状态转换,能帮助开发者更好地设计和管理多线程程序。希望这篇博客对你理解 Java 线程有所帮助!