Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

    • Java并发概述
    • 线程与进程
    • Thread类与线程生命周期
      • 1. Thread 基本用法
      • 2. 线程状态
      • 3. RUNNABLE 不等于正在运行
      • 4. BLOCKED
      • 5. WAITING 与 TIMED_WAITING
      • 6. sleep、wait、join
      • 7. interrupt
      • 8. stop、suspend、resume
      • 9. uncaughtExceptionHandler
      • 10. 线程命名
      • Tips 快问快答
    • 线程创建与任务模型
    • 线程安全
    • synchronized关键字
    • volatile关键字
    • Java内存模型(JMM)
    • 线程间通信
    • 线程池
    • 并发工具类
    • 原子操作类Atomic
    • 并发锁
    • 并发容器
    • ConcurrentHashMap
    • BlockingQueue
    • CopyOnWriteArrayList
    • ThreadLocal
    • Fork/Join框架
    • ScheduledThreadPoolExecutor
    • CompletableFuture
    • 虚拟线程
    • 死锁活锁与线程问题排查
    • 并发编程最佳实践
  • Java IO

  • JVM

目录

Thread类与线程生命周期

Thread 是 Java 表示线程的核心类。学习 Thread 的重点不是记住所有 API,而是理解线程从创建、启动、运行、阻塞、等待到终止的生命周期,以及每个状态背后的触发条件。

# 1. Thread 基本用法

Thread thread = new Thread(() -> {
    System.out.println(Thread.currentThread().getName());
});
thread.start();

start() 会启动新线程,run() 只是普通方法调用。

错误示例:

Thread thread = new Thread(task);
thread.run(); // 不会启动新线程

区别:

方法 行为
start() 请求 JVM 启动新线程,并在新线程中执行 run
run() 当前线程直接调用普通方法

# 2. 线程状态

Java 线程状态定义在 Thread.State 中。

NEW
  │ start
  ▼
RUNNABLE
  │ 获取锁失败
  ▼
BLOCKED

RUNNABLE
  │ wait/join/park
  ▼
WAITING

RUNNABLE
  │ sleep/wait(timeout)/join(timeout)
  ▼
TIMED_WAITING

RUNNABLE
  │ run 方法结束或异常退出
  ▼
TERMINATED

状态说明:

状态 含义
NEW 已创建但未 start
RUNNABLE 可运行,可能正在运行,也可能等待 CPU
BLOCKED 等待进入 synchronized 监视器
WAITING 无限期等待其他线程动作
TIMED_WAITING 带超时时间的等待
TERMINATED 线程执行结束

# 3. RUNNABLE 不等于正在运行

Java 的 RUNNABLE 包含操作系统层面的 ready 和 running。

Java RUNNABLE
├─ 等待 CPU 调度
└─ 正在 CPU 上执行

因此线程 dump 中看到大量 RUNNABLE,不代表它们都在消耗 CPU。需要结合栈信息判断是在计算、IO、Socket 读写,还是 native 调用。

# 4. BLOCKED

BLOCKED 表示线程在等待进入 synchronized 锁。

synchronized (lock) {
    // 线程 A 持有 lock
}

// 线程 B 尝试进入同一个 synchronized 块时进入 BLOCKED

示意:

线程 A 持有 monitor
        │
        ▼
线程 B 竞争 monitor 失败 -> BLOCKED

注意:等待 ReentrantLock 通常不是 BLOCKED,线程状态可能表现为 WAITING,因为它基于 AQS/LockSupport。

# 5. WAITING 与 TIMED_WAITING

进入 WAITING 的常见方式:

  • Object.wait()
  • Thread.join()
  • LockSupport.park()

进入 TIMED_WAITING 的常见方式:

  • Thread.sleep(time)
  • Object.wait(time)
  • Thread.join(time)
  • LockSupport.parkNanos

对比:

状态 是否有超时 唤醒方式
WAITING 没有 其他线程通知或中断
TIMED_WAITING 有 超时、通知或中断

# 6. sleep、wait、join

方法 所属类 是否释放 synchronized 锁 用途
sleep Thread 不释放 当前线程暂停一段时间
wait Object 释放 等待条件变化
join Thread 等待目标线程结束 线程顺序控制

wait 必须在持有对象锁时调用:

synchronized (lock) {
    lock.wait();
}

否则会抛 IllegalMonitorStateException。

# 7. interrupt

interrupt 是线程协作式取消机制。

thread.interrupt();

它不会强行杀死线程,而是:

  • 设置线程中断标记。
  • 如果线程正在 sleep/wait/join,抛出 InterruptedException 并清除中断标记。

正确处理:

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    return;
}

捕获中断异常后,如果当前方法无法处理,应恢复中断标记或向上抛出。

# 8. stop、suspend、resume

这些方法已经不推荐使用:

方法 问题
stop 可能在任意位置释放锁,破坏对象一致性
suspend 暂停线程但不释放锁,容易死锁
resume 与 suspend 配合容易丢失恢复信号

线程停止应使用中断标记、volatile 标志位、任务取消或线程池关闭机制。

# 9. uncaughtExceptionHandler

线程执行中未捕获异常会导致线程终止。

thread.setUncaughtExceptionHandler((t, e) -> {
    log.error("线程异常退出: {}", t.getName(), e);
});

线程池中任务异常要特别关注,否则任务可能静默失败,或者只在 Future 中体现。

# 10. 线程命名

线程名是排查问题的重要线索。

Thread thread = new Thread(task, "order-worker-1");

线程池应通过 ThreadFactory 统一命名:

ThreadFactory factory = runnable -> new Thread(runnable, "order-pool-" + counter.incrementAndGet());

线程 dump、日志、监控中都依赖线程名定位问题。

# Tips 快问快答

Q:start() 和 run() 有什么区别? A:start() 启动新线程,run() 只是当前线程普通方法调用。

Q:线程可以 start 两次吗? A:不能,第二次会抛 IllegalThreadStateException。

Q:RUNNABLE 一定正在运行吗? A:不一定,也可能只是等待 CPU 调度。

Q:BLOCKED 一定是等锁吗? A:在 Java 线程状态里,通常表示等待进入 synchronized 监视器。

Q:sleep 会释放锁吗? A:不会。

Q:wait 会释放锁吗? A:会释放当前对象的监视器锁。

Q:interrupt 会强制停止线程吗? A:不会,它是协作式取消信号。

Q:捕获 InterruptedException 后应该怎么做? A:能处理就处理;不能处理时恢复中断标记或向上抛出。

Q:为什么线程要命名? A:便于日志、线程 dump 和监控定位问题。

Q:为什么不推荐 stop? A:它可能破坏共享对象一致性,造成难以修复的数据问题。

上次更新: 2026/06/24, 17:22:59
线程与进程
线程创建与任务模型

← 线程与进程 线程创建与任务模型→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式