跳转到内容

线程生命周期

来自代码酷

模板:Note

线程生命周期[编辑 | 编辑源代码]

线程生命周期(Thread Lifecycle)是指线程从创建到销毁的整个过程,Java通过

java.lang.Thread

类及其内部状态(

Thread.State

)定义了线程的完整生命周期。理解这些状态及其转换是掌握多线程编程的基础。

线程的6种状态[编辑 | 编辑源代码]

Java线程生命周期包含以下6种状态(JDK 1.5+定义):

stateDiagram-v2 [*] --> NEW NEW --> RUNNABLE: start() RUNNABLE --> TERMINATED: 执行完成/异常退出 RUNNABLE --> WAITING: wait()/join()/LockSupport.park() WAITING --> RUNNABLE: notify()/notifyAll()/LockSupport.unpark() RUNNABLE --> TIMED_WAITING: sleep(n)/wait(n)/join(n) TIMED_WAITING --> RUNNABLE: 超时/唤醒 RUNNABLE --> BLOCKED: 竞争锁失败 BLOCKED --> RUNNABLE: 获取锁成功

详细状态说明[编辑 | 编辑源代码]

NEW(新建)
线程被创建但尚未调用
start()
方法时的状态。此时线程未获得任何系统资源。
RUNNABLE(可运行)
调用
start()
后的状态,包含两种情况:
  • 就绪(Ready):等待CPU分配时间片
  • 运行中(Running):正在执行任务
BLOCKED(阻塞)
线程等待获取同步锁时的状态(例如进入
synchronized
代码块时锁已被其他线程持有)。
WAITING(无限等待)
线程主动调用以下方法进入此状态:
  • Object.wait()
    
    (需配合
    notify()
    
    唤醒)
  • Thread.join()
    
    (等待目标线程终止)
  • LockSupport.park()
    
    (需
    unpark()
    
    唤醒)
TIMED_WAITING(限时等待)
与WAITING类似,但带有超时参数:
  • Thread.sleep(long millis)
    
  • Object.wait(long timeout)
    
  • Thread.join(long millis)
    
TERMINATED(终止)
线程执行完毕或抛出未捕获异常后的最终状态。

代码示例[编辑 | 编辑源代码]

以下示例展示状态转换过程:

public class ThreadLifecycleDemo {
    public static void main(String[] args) throws InterruptedException {
        Object lock = new Object();
        
        Thread t1 = new Thread(() -> {
            synchronized (lock) {
                try {
                    System.out.println("t1进入WAITING状态");
                    lock.wait();  // 进入WAITING
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("t2在RUNNABLE状态");
                try {
                    Thread.sleep(2000);  // 进入TIMED_WAITING
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                lock.notify();  // 唤醒t1
            }
        });

        System.out.println("t1初始状态: " + t1.getState());  // NEW
        t1.start();
        t2.start();
        
        Thread.sleep(500);
        System.out.println("t1调用wait()后状态: " + t1.getState());  // WAITING
        System.out.println("t2睡眠时状态: " + t2.getState());    // TIMED_WAITING
        
        Thread.sleep(2500);
        System.out.println("t1最终状态: " + t1.getState());  // TERMINATED
    }
}

模板:Output

实际应用场景[编辑 | 编辑源代码]

生产者-消费者模型[编辑 | 编辑源代码]

线程状态转换的典型应用,通过

wait()

notify()

协调线程:

class Buffer {
    private Queue<Integer> queue = new LinkedList<>();
    private int capacity;
    
    public Buffer(int capacity) { this.capacity = capacity; }
    
    public synchronized void produce(int item) throws InterruptedException {
        while (queue.size() == capacity) {
            wait();  // 缓冲区满时进入WAITING
        }
        queue.add(item);
        notifyAll();  // 唤醒消费者线程
    }
    
    public synchronized int consume() throws InterruptedException {
        while (queue.isEmpty()) {
            wait();  // 缓冲区空时进入WAITING
        }
        int item = queue.poll();
        notifyAll();  // 唤醒生产者线程
        return item;
    }
}

常见问题[编辑 | 编辑源代码]

模板:QA

模板:QA

状态转换公式[编辑 | 编辑源代码]

线程状态转换可表示为: NEWstart()RUNNABLE获取锁失败BLOCKED获取锁成功RUNNABLE

RUNNABLEwait()WAITINGnotify()RUNNABLE

最佳实践[编辑 | 编辑源代码]

  1. 避免长时间阻塞在WAITING/TIMED_WAITING状态(设置超时)
  2. 使用
    Thread.getState()
    
    进行调试而非业务逻辑
  3. 优先使用
    java.util.concurrent
    
    工具类而非原生API