Appearance
JUC 总览:AQS、锁、原子类、线程池、并发容器到底怎么串起来
很多人学 JUC 时容易出现一种割裂感:
- 知道
ReentrantLock - 知道
ThreadPoolExecutor - 知道
ConcurrentHashMap - 但不知道这些东西在整体里是什么关系
JUC 不是一堆零散类名,而是一整套围绕“并发控制”展开的工具箱。
先说结论
可以把 JUC 粗略拆成 6 组能力:
- 锁与同步器
- 原子类与 CAS
- 并发容器
- 线程池与异步执行
- 线程协作工具
- 并发队列
如果你先把这 6 组关系理顺,再看具体类,学习成本会低很多。
一、JUC 到底在解决什么
JUC 是 java.util.concurrent 包及相关并发工具的统称。
它主要解决的是这些问题:
- 多线程如何安全共享数据
- 多线程如何协调执行顺序
- 如何减少锁竞争带来的性能损耗
- 如何更稳定地管理异步任务
也就是说,JUC 并不只关心“加锁”,它关心的是整套并发程序怎么写得更稳。
二、第一组:锁与同步器
这是最容易接触到的一组。
典型类包括:
ReentrantLockReentrantReadWriteLockStampedLockCountDownLatchSemaphoreCyclicBarrier
其中一个非常关键的底座是:
AQS
很多同步器本质上都是基于 AQS 扩展出来的。
如果你已经看过:
那这一组已经有了一个不错的起点。
三、第二组:原子类与 CAS
当你只是做单变量原子更新时,未必需要真的上锁。
这一组典型包括:
AtomicIntegerAtomicLongAtomicReferenceLongAdder
这组工具的核心思想是:
- 利用 CAS 做乐观更新
适合:
- 计数
- 状态位更新
- 单变量原子操作
但它的边界也很清楚:
- 多变量一致性通常不能只靠原子类
可以结合这篇一起看:
四、第三组:并发容器
多线程下共享集合是非常高频的场景。
JUC 给出的典型方案包括:
ConcurrentHashMapCopyOnWriteArrayListConcurrentLinkedQueueBlockingQueue家族
它们的重点不是“都线程安全”,而是:
- 在不同读写特征下,用不同机制换吞吐和一致性
例如:
ConcurrentHashMap更适合高并发读写CopyOnWriteArrayList更适合读多写少
五、第四组:线程池与异步执行
实际项目里,线程一般不应该手动无限创建。
这一组的核心类通常有:
ThreadPoolExecutorScheduledThreadPoolExecutorFutureCompletableFuture
线程池关注的是:
- 任务怎么调度
- 队列怎么堆积
- 线程数怎么控制
- 异常怎么处理
相关文章可以串起来看:
六、第五组:线程协作工具
这一组更关心“多个线程怎么配合”。
常见类:
CountDownLatchCyclicBarrierSemaphorePhaserExchanger
它们并不主要解决共享变量互斥,而是解决:
- 谁先执行
- 谁等谁
- 同时放行多少线程
七、第六组:并发队列
队列在 JUC 里非常重要,因为它连接了:
- 生产者消费者模型
- 线程池任务排队
- 削峰与异步处理
常见类型:
ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueueDelayQueueSynchronousQueue
很多线程池问题,本质上都和队列特性有关。
八、JUC 更适合怎么学
如果从实用角度出发,我更建议按这条顺序:
- 先学线程安全基本概念
- 学
synchronized、volatile、CAS - 学
ReentrantLock、AQS - 学线程池
- 学并发容器
- 学
CompletableFuture和协作工具
这样会比“从头背类名”更容易形成整体感。
九、JUC 最常见的误区
1. 把 JUC 理解成“高性能加锁包”
它远不止锁,还包含任务编排、协作、容器和异步模型。
2. 觉得并发工具越高级越该优先用
很多业务场景里:
- 简单清晰
- 行为可预测
比“听起来更高级”更重要。
3. 学了类名,却没建立场景映射
真正有用的是看到问题时能想到:
- 这是互斥问题
- 这是线程协作问题
- 这是任务调度问题
- 这是容器读写模型问题
一句话总结
JUC 本质上是一整套并发编程工具体系,不是几个孤立类名。
先把“锁、原子类、容器、线程池、协作工具、队列”这 6 组关系串起来,再深入具体实现,会更容易建立稳定的并发知识框架。