现代Java并发编程需按“问题驱动+分层脉络”组织,聚焦线程本身、共享资源、协作机制三类对象,分线程生命周期、线程安全三要素、JUC工具选型、线程池治理四方向系统复习。

现代 Java 并发编程的复习不能靠零散记忆,得按“问题驱动 + 分层脉络”来组织。核心是抓住三类对象:线程本身、共享资源、协作机制。下面分四个关键方向展开,每一块都直指高频实践痛点。
一、理清线程生命周期与创建方式的本质区别
很多并发问题其实源于对线程启动机制的误解。重点不是记状态名,而是理解状态切换背后的资源行为:
- start() vs run():调用 start() 才触发 JVM 分配栈空间并调度;直接调 run() 只是普通方法调用,毫无并发意义
- Runnable 和 Callable 的分工:Runnable 适合无返回、不抛检异常的任务;Callable 配合 Future 才能安全获取结果和异常,比如异步查数据库后聚合数据
- 为什么推荐 Runnable 而非继承 Thread:Java 单继承限制下,实现接口更利于组合(例如一个任务既需定时又需限流,可包装多个 Runnable)
二、吃透线程安全三要素的落地表现
原子性、可见性、有序性不是概念背诵题,而是每次写共享变量时都要问自己的三个问题:
- 原子性破坏的典型场景:i++、map.put(k, v) 在高并发下会丢更新;解决不是一律加锁,而是按场景选——计数用 AtomicInteger,集合操作优先 ConcurrentHashMap
- volatile 的真实边界:它能保证 flag = true 立即被其他线程看到,但不能保证 if (flag) { doSomething(); } 这段代码的原子执行;常用于状态标记、双重检查单例里的 instance 引用
- 有序性靠 happens-before 规则约束:synchronized 块结尾、volatile 写、Thread.start() 等都会建立该规则;编译器和 CPU 不会将这些动作之后的读写重排序到其前面
三、掌握 JUC 工具类的选型逻辑
JUC 不是工具箱,而是一套有明确职责边界的协作协议。复习时要建立“问题→工具→原理”映射:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
立即学习“Java免费学习笔记(深入)”;
- 锁的选择:简单同步优先 synchronized(JDK 自动优化);需要超时、中断、公平性或条件等待时,才用 ReentrantLock + Condition
- 集合类不能凭名字选:CopyOnWriteArrayList 适合读极多、写极少(如监听器列表);ConcurrentHashMap 适合读写均衡;若写远多于读,考虑分段加锁或队列缓冲
- 协作工具各司其职:CountDownLatch 用于“一个线程等多个任务完成”;CyclicBarrier 是“多个线程互相等彼此到达”;Semaphore 控制并发访问数量(如连接池限流)
四、线程池不是配置参数,而是资源治理策略
ThreadPoolExecutor 的每个参数都对应一种系统风险控制点,复习时要关联真实瓶颈:
- corePoolSize 不是“常用线程数”:它是长期维持的最小工作线程,设太小会导致频繁扩容;设太大则空转耗资源。建议参考系统平均 QPS × 平均响应时间(单位:线程秒)
- workQueue 类型决定拒绝时机:SynchronousQueue 不缓存任务,直接触发拒绝策略;LinkedBlockingQueue 容量大但易掩盖负载问题;生产环境推荐 ArrayBlockingQueue 并设合理容量
- 拒绝策略不是兜底,而是降级信号:CallerRunsPolicy 让调用线程自己执行,可自然减缓上游流量;DiscardOldestPolicy 适合任务有时效性(如实时行情推送)
不复杂但容易忽略:所有并发工具都依赖正确的内存模型理解。复习时随手写两行代码验证 volatile 可见性、synchronized 锁对象范围、线程池 submit 后 get() 是否阻塞——动手比看十遍源码更管用。


















