Java中的线程生命周期可以划分为五个主要状态:新建(New)、可运行(Runnable)、运行(Running)、阻塞(Blocked)、等待(Waiting)和终止(Terminated)。每个状态代表线程在其生命周期中的不同阶段。下面是对每个状态的详细解释及其转换过程。
1. 新建(New)
当一个线程对象被创建时,线程处于新建状态。这时线程对象已经创建,但还没有调用 start()
方法。
Thread thread = new Thread();
2. 可运行(Runnable)
当调用线程的 start()
方法时,线程进入可运行状态。处于可运行状态的线程已经被线程调度器(Scheduler)安排执行,但具体何时开始运行由操作系统决定。
thread.start();
3. 运行(Running)
线程被线程调度器选择,开始执行其 run()
方法时,线程进入运行状态。在任意时刻,只有一个可运行的线程会被选中并进入运行状态。
public void run() {
// Thread is in running state
}
4. 阻塞(Blocked)
线程在尝试获取一个已经被其他线程占用的对象锁时,进入阻塞状态。当持有该锁的线程释放锁后,阻塞线程变为可运行状态。
synchronized (lock) {
// Thread may block if lock is held by another thread
}
5. 等待(Waiting)
线程等待其他线程显式地唤醒时,进入等待状态。线程进入等待状态通过调用 Object.wait()
或 Thread.join()
,或通过 Lock
的 Condition.await()
方法。线程只有在其他线程调用 Object.notify()
、Object.notifyAll()
、或 Thread.interrupt()
方法后,才能从等待状态变为可运行状态。
synchronized (lock) {
lock.wait(); // Thread is in waiting state
}
6. 超时等待(Timed Waiting)
线程等待一定的时间后自动唤醒。线程通过 Thread.sleep(long millis)
、Object.wait(long timeout)
、或 Thread.join(long millis)
等方法进入超时等待状态。
Thread.sleep(1000); // Thread is in timed waiting state for 1 second
7. 终止(Terminated)
线程运行结束或因异常退出其 run()
方法时,进入终止状态。线程一旦进入终止状态,不能再次运行。
public void run() {
// Thread will terminate after executing this block
}
状态转换图
New -> Runnable -> Running -> Terminated
^ | ^ |
| | | |
| | Timed /|\
| / \ Waiting |
| / \ | |
| Blocked <- Waiting |
\ /
\______________________/
线程状态转换
-
新建(New) 到 可运行(Runnable):
- 通过调用
start()
方法。
- 通过调用
-
可运行(Runnable) 到 运行(Running):
- 线程调度器选择当前线程执行。
-
运行(Running) 到 阻塞(Blocked):
- 线程试图获取一个已经被其他线程持有的锁。
-
阻塞(Blocked) 到 可运行(Runnable):
- 线程成功获取所需的锁。
-
运行(Running) 到 等待(Waiting):
- 通过调用
wait()
、join()
、或Lock
的Condition.await()
方法。
- 通过调用
-
等待(Waiting) 到 可运行(Runnable):
- 其他线程调用
notify()
、notifyAll()
或interrupt()
方法。
- 其他线程调用
-
运行(Running) 到 超时等待(Timed Waiting):
- 通过调用
sleep(long millis)
、wait(long timeout)
、或join(long millis)
方法。
- 通过调用
-
超时等待(Timed Waiting) 到 可运行(Runnable):
- 超时时间到期或被其他线程唤醒。
-
运行(Running) 到 终止(Terminated):
- 线程运行结束或因异常退出。
这些状态及其转换共同描述了Java线程的生命周期,从创建到终止的完整过程。通过理解这些状态,可以更好地编写和调试多线程程序。