← [ BACK_TO_NOTES ]

Java 线程与 Runnable

Thread 与 Runnable 如何启动并发任务:线程生命周期入口、start/run 区别与基本退出意识。

#concept #growing #dev #java

[!info] related notes

Java 线程与 Runnable

这个概念为什么出现

服务要同时处理多个请求、后台刷新缓存、异步发消息。Java 的经典并发起点是 线程(Thread) 与任务抽象 Runnable/Callable。先分清“任务”和“执行线程”,后面的线程池才有意义。

[!abstract] 一句话理解 Runnable 描述要做的事;Thread.start() 才会真正启动新线程并发执行,直接调用 run() 只是普通方法调用。

最小可运行示例

场景:启动审计日志线程,并等待教学任务完成

public class AuditAsync {
    static void handleOrder(String orderId) throws InterruptedException {
        // 教学:先打印受理消息;本函数随后 join,会等到审计线程结束
        System.out.println("accepted " + orderId + " on " + Thread.currentThread().getName());

        Thread audit = new Thread(() -> {
            // 审计任务:模拟写日志
            System.out.println("audit " + orderId + " on " + Thread.currentThread().getName());
        }, "audit-worker");
        audit.start(); // 启动并发,而不是 audit.run()
        audit.join();  // 演示中等待结束;真实服务常用线程池且不在请求线程 join
    }

    public static void main(String[] args) throws Exception {
        handleOrder("ORD-1");
    }
}

建议运行:

javac AuditAsync.java && java AuditAsync

期望输出(线程名可能略有差异,但 audit 行应出现):

accepted ORD-1 on main
audit ORD-1 on audit-worker

结合场景再看三个关注点

  1. start 才创建新并发执行。
  2. 任务里未捕获的异常默认不会回到 main。
  3. 平台线程任务通常交给受控 Executor,避免无限制 new Thread;虚拟线程也需单独限制数据库连接等稀缺资源。

核心概念与准确模型

1. 线程 vs 任务

  • 任务:Runnable/Callable
  • 执行者:Thread 或 Executor

2. 生命周期直觉

NEW → RUNNABLE → 阻塞/等待 → TERMINATED(简化)

3. 中断

  • interrupt 协作式取消
  • 可中断的阻塞调用抛 InterruptedException 时通常会清除中断状态;可向上抛出,或在捕获后恢复状态并退出/取消,不应吞掉。
  • interrupt 不保证终止线程,也不是所有阻塞 I/O 都会因此抛 InterruptedException。\

4. 守护线程

  • 平台线程在 start 前可设置 setDaemon(true);daemon 线程不阻止 JVM 退出,不能依赖它完成关键事务。内存中的后台任务也不提供持久交付保证。

边界情况与反直觉行为

  1. 共享可变状态无同步 → 数据竞争(见后文)。
  2. join 死等导致请求线程卡死。
  3. 一个 Thread 实例只能 start 一次,结束后也不能重新启动;再次调用会抛 IllegalThreadStateException。
  4. 线程名对排障极重要。\

常见误区

[!warning] 常见误区:用 Thread.sleep 当同步协议 sleep 不能保证可见性/事件顺序;用锁、并发工具或 join/future。

工程实践

  1. 业务代码面向 Executor。
  2. 命名线程。
  3. 设置未捕获异常处理器。
  4. 明确取消与超时策略。

本节总结

  • Runnable 是任务,Thread 是载体
  • start ≠ run
  • 为线程池与同步打基础

自测题

  1. 为什么不要在生产循环里无限 new Thread?
  2. 捕获 InterruptedException 后应怎样处理中断状态?
参考答案
  1. 无法统一限流、复用与关闭,易耗尽资源。
  2. 能传播则继续抛出 InterruptedException;否则通常恢复中断标志并结束/取消任务,避免吞掉信号后继续正常工作。

延伸阅读与资料来源

资料类型支撑内容
Thread (API)API线程
Concurrency (Oracle Tutorial)教程并发入门
创建于 2026/7/15 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本