Java 面试题:并发进阶 JUC 与线程池实战

一、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 如何减少锁竞争——讲清机制与权衡即可。