Java线程的生命周期是指线程从创建到终止的整个过程。Java中线程的状态由 java.lang.Thread.State
枚举类定义,包含新建(New)
、就绪(Runnable)
、阻塞(Blocked)
、等待 (Waiting)
、计时等待(Timed_Waiting)
、终止(Terminated)
这6种核心状态。本文将深入解析Java线程的生命周期、六种核心状态及其转换规则,并结合代码示例帮助读者掌握实际应用技巧。
new Thread()
创建线程对象,但未调用 start()
方法。start()
。public class ThreadLifecycleExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> System.out.println("Thread is running."));
// 线程处于新建状态
System.out.println("Thread State: " + thread.getState()); // 输出 NEW
}
}
start()
方法后。RUNNABLE
包含操作系统中的 “就绪” 和 “运行” 状态。public class ThreadLifecycleExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("Thread is running.");
});
thread.start();
System.out.println("Thread State after start(): " + thread.getState()); // 输出 RUNNABLE
}
}
synchronized
同步块)。RUNNABLE
状态。public class BlockedExample {
public static void main(String[] args) {
Object lock = new Object();
Thread thread1 = new Thread(() -> {
synchronized (lock) {
try {
Thread.sleep(5000); // 保持锁5秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(() -> {
synchronized (lock) {
System.out.println("Thread 2 acquired the lock.");
}
});
thread1.start();
thread2.start();
}
}
wait()
、join()
或 LockSupport.park()
进入无限等待状态。Object.wait()
:等待其他线程调用 notify()
/notifyAll()
。Thread.join()
:等待某个线程终止。LockSupport.park()
:线程暂停。notify()
)才能恢复执行。public class WaitingExample {
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
Thread thread = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("Thread is waiting.");
lock.wait(); // 线程进入等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread resumed.");
}
});
thread.start();
Thread.sleep(1000); // 主线程暂停1秒
synchronized (lock) {
lock.notify(); // 唤醒等待线程
}
}
}
Thread.sleep(millis)
:线程休眠指定时间。Object.wait(millis)
:等待指定时间后自动唤醒。Thread.join(millis)
:等待指定时间后放弃。LockSupport.parkNanos(nanos)
:暂停指定时间。RUNNABLE
状态。public class TimedWaitingExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
try {
System.out.println("Thread is sleeping.");
Thread.sleep(2000); // 线程进入计时等待状态
System.out.println("Thread woke up.");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
}
}
run()
方法。public class TerminatedExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> System.out.println("Thread is running."));
thread.start();
try {
thread.join(); // 等待线程终止
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread State: " + thread.getState()); // 输出 TERMINATED
}
}
源状态 | 目标状态 | 触发条件 | 典型方法/场景 |
---|---|---|---|
NEW | RUNNABLE | 调用 start() 方法 |
Thread t = new Thread(); t.start(); |
RUNNABLE | BLOCKED | 竞争 synchronized 锁失败 |
多线程访问同步代码块或方法 |
RUNNABLE | WAITING | 调用 wait() 、join() 或 LockSupport.park() |
Object.wait() 、Thread.join() 、LockSupport.park() |
RUNNABLE | TIMED_WAITING | 调用 sleep(ms) 、wait(ms) 、join(ms) 、parkNanos(...) |
Thread.sleep(1000) 、Object.wait(1000) 、LockSupport.parkNanos(1000) |
RUNNABLE | TERMINATED | run() 方法执行完毕或抛出未捕获异常 |
正常结束或异常终止 |
BLOCKED | RUNNABLE | 获取到锁(锁被释放) | 线程竞争的锁被其他线程释放 |
WAITING | RUNNABLE | 被 notify() 、notifyAll() 、unpark() 或 interrupt() 唤醒 |
Object.notify() 、LockSupport.unpark() 、Thread.interrupt() |
TIMED_WAITING | RUNNABLE | 超时、被 notify() 、notifyAll() 、unpark() 或 interrupt() 唤醒 |
Object.wait(1000) 、Thread.sleep(1000) 、LockSupport.parkNanos(1000) |
TERMINATED | 无 | 终态,不可逆 | 线程结束运行 |
以下是Java线程状态转换的UML图:
+----------------+
| NEW |
+--------+-------+
|
| start()
v
+--------+----------------+
| RUNNABLE |
+--------+----------------+
|
| 竞争锁失败
v
+--------+----------------+
| BLOCKED |
+--------+----------------+
|
| 锁释放
v
+--------+----------------+
| RUNNABLE |
+--------+----------------+
|
| wait(), join(), park()
v
+--------+----------------+
| WAITING |
+--------+----------------+
|
| notify(), unpark(), interrupt()
v
+--------+----------------+
| RUNNABLE |
+--------+----------------+
|
| sleep(), wait(ms), join(ms), parkNanos(...)
v
+--------+----------------+
| TIMED_WAITING |
+--------+----------------+
|
| 超时/notify()/unpark()/interrupt()
v
+--------+----------------+
| RUNNABLE |
+--------+----------------+
|
| run()结束或异常
v
+--------+----------------+
| TERMINATED |
+-------------------------+
start()
方法。Thread t = new Thread(() -> System.out.println("Running"));
t.start(); // NEW → RUNNABLE
synchronized
锁。Object lock = new Object();
Thread t1 = new Thread(() -> {
synchronized (lock) {
// 持有锁
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
// 竞争失败 → BLOCKED
}
});
t1.start(); // 先启动t1
Thread.sleep(100); // 确保t1先获取锁
t2.start(); // t2进入BLOCKED状态
t1
释放锁后,t2
重新进入 RUNNABLE
状态。Object.wait()
(无超时)Thread.join()
(无超时)LockSupport.park()
(无超时)Object lock = new Object();
Thread t = new Thread(() -> {
synchronized (lock) {
lock.wait(); // RUNNABLE → WAITING
}
});
t.start();
Thread.sleep(ms)
(休眠)Object.wait(ms)
(带超时)Thread.join(ms)
(带超时)LockSupport.parkNanos(...)
(带超时)Thread.sleep(1000); // RUNNABLE → TIMED_WAITING
run()
方法执行完毕或抛出未捕获异常。Thread t = new Thread(() -> {
System.out.println("Task done"); // 执行完毕 → TERMINATED
});
t.start();
Object.notify()
/ notifyAll()
LockSupport.unpark()
Thread.interrupt()
Object lock = new Object();
Thread t1 = new Thread(() -> {
synchronized (lock) {
lock.wait(); // 进入WAITING
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
lock.notify(); // 唤醒t1 → RUNNABLE
}
});
t1.start();
t2.start();
notify()
、notifyAll()
、unpark()
或 interrupt()
。Object lock = new Object();
Thread t = new Thread(() -> {
synchronized (lock) {
lock.wait(1000); // 等待1秒后自动唤醒 → RUNNABLE
}
});
t.start();
pthread_create()
创建线程。CreateThread()
创建线程。start()
(如 Java)或 pthread_create()
→ 转换到 就绪(Ready)。RUNNABLE
状态包括就绪和运行状态。run()
方法)。sleep()
、wait()
)或被动阻塞(如等待 I/O 操作)退出运行状态。sleep()
、wait()
或等待锁 → 转换到 阻塞(Blocked)。sleep()
、wait()
、join()
)。notify()
/notifyAll()
→ 唤醒等待线程。return
、exit()
。SIGKILL
信号、抛出未捕获的异常。BLOCKED
、WAITING
、TIMED_WAITING
是导致线程无法执行的原因。tryLock()
(ReentrantLock
提供)尝试获取锁。synchronized
:确保同一时间只有一个线程访问共享资源。volatile
:保证变量的可见性(但不提供原子性)。ReentrantLock
:提供比 synchronized
更灵活的锁机制。interrupt()
:请求线程停止(需主动检查中断状态)。Thread t = new Thread(() -> {
try {
Thread.sleep(1000); // 进入TIMED_WAITING
} catch (InterruptedException e) {
// 中断WAITING/TIMED_WAITING线程,抛出 `InterruptedException`,线程转回 `RUNNABLE`
System.out.println("Interrupted");
}
});
t.start();
t.interrupt(); // 中断线程
Executors.newFixedThreadPool(n)
:固定大小线程池。Executors.newCachedThreadPool()
:缓存线程池。Java线程的生命周期由6种状态组成,每种状态对应不同的执行阶段和资源需求。理解这些状态及其转换规则是开发高效并发程序的基础。实际开发中需注意线程同步、死锁避免和资源管理,合理使用线程池和中断机制,以提升程序的性能和稳定性。