一、CAS 与原子类
AtomicInteger 等原子类靠 CAS(Compare-And-Swap) 无锁更新:预期值等于内存值才改,否则重试。优点无锁高并发,缺点有 ABA 问题(值被改回原值,CAS 误判)——用 AtomicStampedReference 加版本号解决。
二、ReentrantLock 深入
| 维度 | 要点 |
|---|---|
| 公平性 | 公平锁按排队,非公平锁可插队(默认,吞吐高) |
| Condition | 替代 wait/notify,支持多等待队列 |
| 可重入 | 同一线程可重复获取,计数释放 |
三、线程池参数实战
ThreadPoolExecutor(core, max, keepAlive, unit, queue, handler) 提交任务流程:
核心线程满? -> 入队列 -> 队列满? -> 开到最大线程 -> 还满? -> 拒绝策略
| 拒绝策略 | 行为 |
|---|---|
| AbortPolicy | 抛异常(默认) |
| CallerRunsPolicy | 调用者线程自己跑,削峰 |
| DiscardOldest | 丢最老任务 |
| Discard | 静默丢弃 |
选型:CPU 密集 core≈核数;IO 密集 core 可更大;队列用有界防 OOM;别用 Executors 无界队列。
四、ConcurrentHashMap 深入(JDK 1.8)
- 结构:数组 + 链表 / 红黑树,与 HashMap 一致;
- 写时只锁头节点(
synchronized+ CAS),并发度远高于 1.7 的分段锁; size()用 baseCount + CounterCell 分段计数,避免全局锁;- 扩容时多线程协助迁移(transfer)。
五、并发工具三件套
| 工具 | 用途 |
|---|---|
| CountDownLatch | 等 N 个任务完成再继续(一减到底) |
| CyclicBarrier | 等 N 个线程到齐再一起跑(可重用) |
| Semaphore | 限并发数(如限流) |
Java 并发面试区分度在”为什么”:CAS 的 ABA、线程池为什么用有界队列、CHM 如何减少锁竞争——讲清机制与权衡即可。