JUC
一、并发的第一性问题空间(Why 并发工具存在)
所有 Java 并发工具,本质上都在解决有限计算资源在多执行主体之间的分配与协调问题。
从第一性原理出发,并发系统只存在五类不可约的问题:
1. 互斥(Mutual Exclusion)
- 同一时刻,**共享资源只能被一个线程修改**
- 本质冲突:写-写、读-写冲突
2. 可见性(Visibility)
- 一个线程对共享状态的修改,**何时、如何被其他线程观察到**
3. 协调(Coordination)
- 多个线程之间需要**在时间或阶段上达成一致**
- 不是竞争,而是协作
4. 资源限流(Throttling)
- 资源有限(连接、线程、IO),需要控制**同时访问者数量**
5. 上下文隔离与传播(Context Management)
- 并发执行下,如何**安全地保存、传递线程上下文**
所有 JUC 工具,都可以被映射回上述问题之一或组合。
二、Java 并发的总体架构分层(How Java 解决并发)
并发问题空间
↓
并发抽象模型(锁 / 同步器 / 限流器 / 上下文)
↓
并发框架(AQS)
↓
具体工具类(ReentrantLock / Semaphore / CountDownLatch ...)
这一分层体现了 稳定性递增原则:
三、AQS:Java 并发的“内核抽象”
3.1 AQS 的设计哲学
AQS(AbstractQueuedSynchronizer)并不是“锁”,而是:
竞争失败线程的统一管理框架
它抽象了并发控制中最稳定的三件事:
- **资源状态(state)**:资源是否可用
- **等待队列(FIFO)**:竞争失败者排队
- **阻塞 / 唤醒机制**:最小化 CPU 空转
3.2 AQS 的核心模型
state(int) → 资源状态机
同步队列(CLH变体) → 管理竞争失败线程
条件队列 → 管理协作型等待
AQS 通过模板方法模式,将策略交给子类:
- tryAcquire / tryRelease
- tryAcquireShared / tryReleaseShared
而将调度、排队、阻塞统一托管。
四、互斥问题:ReentrantLock 与 synchronized
4.1 抽象模型
- **互斥锁 = 状态机 + 排队规则**
- 可重入性本质:**线程身份绑定 + 计数状态**
4.2 公平性:一种资源分配哲学
| 策略 |
价值取向 |
代价 |
| 公平锁 |
顺序正义 |
吞吐下降 |
| 非公平锁 |
系统效率 |
局部饥饿 |
公平性不是技术问题,而是系统价值判断。
4.3 synchronized vs ReentrantLock
| 维度 |
synchronized |
ReentrantLock |
| 实现层 |
JVM |
JDK |
| 锁释放 |
自动 |
手动 |
| 公平性 |
非公平 |
可配置 |
| 中断 |
不支持 |
支持 |
工程哲学:
能用 synchronized,就不要用 Lock。
五、读写分离:ReentrantReadWriteLock 与 StampedLock
5.1 读写锁的核心矛盾
- **读多写少**是常态
- 写操作必须独占
- 读操作应最大化并发
5.2 ReentrantReadWriteLock
- 悲观并发模型
- 明确区分读 / 写
- 存在写饥饿与调度复杂性
5.3 StampedLock:乐观并发的引入
- 核心思想:**先假设没有写冲突**
- 失败再回退为悲观锁
这是从“锁竞争”向“冲突检测”的范式迁移。
六、协作而非竞争:同步器模型
6.1 CountDownLatch —— 一次性门闩
6.2 CyclicBarrier —— 阶段性对齐
- 模型:**阶段同步点**
- 可复用
- 适用于迭代式并行计算
6.3 两者的本质区别
| 维度 |
CountDownLatch |
CyclicBarrier |
| 关注点 |
完成 |
对齐 |
| 是否可复用 |
否 |
是 |
| 思维模型 |
门闩 |
栅栏 |
七、资源限流:Semaphore
7.1 抽象模型
- **计数型共享资源控制器**
- 本质不是锁,而是**配额**
7.2 工程意义
八、线程间数据交换与通信
8.1 Exchanger
8.2 LockSupport
- park / unpark 是 JVM 层的线程调度原语
- AQS 的基础设施
九、上下文管理:ThreadLocal 及其演进
9.1 ThreadLocal 的本质
线程私有上下文容器
解决的是:
并发环境下的隐式参数传递问题
9.2 核心风险
- 线程池复用 → 脏数据
- 生命周期不一致 → 内存泄漏
9.3 InheritableThreadLocal 的局限
9.4 TransmittableThreadLocal(TTL)
- 本质:**上下文快照 + 回放机制**
- 是对 ThreadLocal 在现代并发模型下的修正
十、工具选型的稳定方法论
| 并发问题 |
首选工具 |
原因 |
| 简单互斥 |
synchronized |
简单、安全 |
| 高并发互斥 |
ReentrantLock |
可控策略 |
| 读多写少 |
StampedLock |
乐观并发 |
| 任务协作 |
CountDownLatch |
一次性同步 |
| 阶段并行 |
CyclicBarrier |
可复用 |
| 资源保护 |
Semaphore |
配额控制 |
| 上下文传递 |
TTL |
线程池友好 |
关联内容(自动生成)
- [/编程语言/JAVA/JAVA并发编程/基础概念.html](/编程语言/JAVA/JAVA并发编程/基础概念.html) 涵盖原子性、可见性和有序性等基本概念,这些是所有并发工具的基础理论
- [/编程语言/JAVA/JAVA并发编程/线程.html](/编程语言/JAVA/JAVA并发编程/线程.html) 详细介绍了线程模型,这是所有并发工具协调的基础
- [/编程语言/JAVA/JAVA并发编程/线程池.html](/编程语言/JAVA/JAVA并发编程/线程池.html) 讨论了线程池,其中大量使用了诸如CountDownLatch和Semaphore等并发工具
- [/编程语言/JAVA/JAVA并发编程/并发集合.html](/编程语言/JAVA/JAVA并发编程/并发集合.html) 涵盖并发集合,这些集合通常与并发工具类协同工作
- [/编程语言/JAVA/JAVA并发编程/JAVA并发编程.html](/编程语言/JAVA/JAVA并发编程/JAVA并发编程.html) 提供Java并发编程的整体框架,展示了并发工具在整个并发编程体系中的位置