一、线程状态概览
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 线程有所帮助!