Java 线程

一、并发的第一性问题:为什么需要线程?

在任何并发系统中,都必须回答三个根本问题:

  1. **执行单元是什么?**(谁在运行)
  2. **如何被调度?**(谁决定何时运行)
  3. **如何等待与协作?**(如何处理依赖与阻塞)

1.1 执行单元的抽象

线程 = 可被调度的最小执行上下文

一个线程本质上由以下要素构成:

线程并不拥有资源,资源属于进程;线程只是共享资源上的执行路径。


二、进程与线程:资源与执行的分离

2.1 进程的本质角色

进程 = 资源容器

2.2 线程的本质角色

线程 = 调度与执行的载体

同一进程内的线程:

这正是 Java 并发模型选择“共享内存 + 线程”的根本原因。


三、Java 线程模型的设计哲学

3.1 Java 为什么直接建模 Thread?

Java 选择 Thread 作为一等公民,背后隐含了三条设计哲学:

  1. **拥抱操作系统调度**(而非自建调度器)
  2. **阻塞是合法且可表达的语义**
  3. **并发通过共享内存完成,而非消息复制**

这决定了:

3.2 平台线程模型(传统 Java)

Java Thread ≈ OS Native Thread

特点:

这是 Java 并发长期以来的性能与伸缩性瓶颈。


四、线程的抽象层次结构(核心升维)

4.1 抽象层(稳定、不变)

4.2 JVM 实现层(相对稳定)

4.3 工程使用层(易变)

理解并发的关键,在于始终知道自己处在哪一层。


五、Runnable / Callable / Thread:职责拆分模型

5.1 核心思想:执行与调度解耦

抽象职责
Runnable / Callable描述“要做什么”
Thread描述“如何被调度执行”

这是一种典型的 Command + Executor 思想。

5.2 为什么推荐 Runnable 而非继承 Thread

Thread 是执行载体,不应承载业务逻辑。


六、线程生命周期与状态机(行为模型)

6.1 状态机的本质意义

线程状态并非 API 细节,而是:

调度器与同步原语协作的结果

核心状态语义:

6.2 join / wait 的统一原理

并发的安全性来自:

约定 + 协作,而非抢占式控制


七、线程调度的不可控性原则

7.1 抢占式调度的现实

7.2 设计原则

不要试图通过 Thread API 精确控制执行顺序

正确做法:


八、虚拟线程:并发模型的范式升级

8.1 虚拟线程解决的根本问题

阻塞语义 vs 资源利用率 的长期冲突

传统模型的问题不是“线程慢”,而是:

8.2 虚拟线程的本质

虚拟线程 = 用户态调度的执行上下文

关键特征:

8.3 虚拟线程在并发模型中的位置

模型核心思想代价
线程池控制线程数量编程复杂度
Reactor非阻塞 IO心智负担
虚拟线程阻塞语义 + 协程调度JVM 实现复杂度

虚拟线程降低了并发编程的门槛,而非替代所有模型。


九、统一视角下的线程哲学

9.1 Java 并发的核心信条

9.2 面向未来的稳定认知


十、总结

线程不是并发的目的,而是并发的一种表达方式。

理解线程,最终是理解:

关联内容(自动生成)