一、并发基础概念
1. 串行、并发、并行的区别(✅ 高频面试题)
- 串行:任务依次执行,无重叠。
- 并发:多个任务交替执行(逻辑上“同时”),适用于单核 CPU。
- 并行:多个任务真正同时执行,需多核支持。
✅ 面试重点:能结合 CPU 核心数、任务类型(CPU 密集 vs IO 密集)解释适用场景。
2. 为什么必须调用 start() 而不是 run()?
- start():由 JVM 创建新线程并调度执行 run()。
- 直接调用 run():仅在当前线程执行,无并发效果。
3. 如何优雅终止线程?
- 使用 volatile boolean flag 控制循环退出。
- 配合 Thread.interrupt() 中断阻塞操作(如 sleep、wait)。
- **禁止使用 stop()**(已废弃,会导致状态不一致)。
4. ThreadLocal 内存泄漏原因(✅ 高频考点)
- ThreadLocal 的值存储在 Thread 对象的 ThreadLocalMap 中。
- 若 Thread 生命周期长(如线程池),而 ThreadLocal 未 remove(),则 value 无法被 GC。
- 解决方案:使用完务必调用 remove()。
二、Java 内存模型与原子性
1. volatile 能保证原子性吗?
- 不能!volatile 仅保证可见性和禁止指令重排序。
- 对于复合操作(如 i++),仍需 synchronized 或原子类。
2. 高并发累加:AtomicLong vs LongAdder(✅ 高频对比题)
- AtomicLong:基于 CAS,高竞争下大量重试,性能下降。
- LongAdder:分段累加(Cell 数组),最终求和,高并发下性能更优。
- 结论:统计类场景优先用 LongAdder。
三、锁机制深度剖析
1. Synchronized 锁升级流程
偏向锁 → 轻量级锁(CAS + 自旋) → 重量级锁(OS 级互斥)
2. 轻量级锁失败后会直接挂起吗?
- 不会!会先进行自旋(默认 10 次),失败后才升级为重量级锁并挂起线程。
3. CAS(乐观锁) vs Synchronized(悲观锁)谁更快?
- 低竞争:CAS 更快(无锁开销)。
- 高竞争:Synchronized(经 JVM 优化后)可能更稳定,避免 CAS 大量重试。
- 结论:无绝对优劣,需结合场景。
4. 为什么 wait() 必须在 while 循环中?
- 防止虚假唤醒(spurious wakeup):线程可能在未被 notify 的情况下醒来。
- if 会导致条件不满足时继续执行,引发逻辑错误。
5. ReentrantLock vs Synchronized 性能
- JDK 1.6 后 Synchronized 经过大幅优化(锁消除、锁粗化、自旋等)。
- 一般场景两者性能接近,但 ReentrantLock 提供更多功能(超时、公平锁、Condition)。
四、并发容器与 COW 思想
1. HashMap 为什么线程不安全?
- 扩容时形成环形链表(JDK7)。
- 数据覆盖:多个线程 put 相同 key 时可能丢失更新。
2. Copy-on-Write(COW)详解(✅ 阿里面试题)
- 原理:写操作时复制整个底层数组,读操作无锁。
- 适用场景:读远多于写(如监听器列表、配置缓存)。
- 优点:读无锁、线程安全。
- 缺点:写开销大、内存占用高、数据弱一致性。
- 典型实现:CopyOnWriteArrayList、CopyOnWriteArraySet。
五、线程池设计与调优
1. 核心线程数计算(✅ 实战高频题)
案例:1 万 QPS,接口耗时 500ms(0.5s)
- 单机每秒处理能力 = 核心线程数 × (1 / 0.5) = 核心线程数 × 2
- 设单机部署 N 个核心线程,则单机 QPS = 2N
- 要支撑 10,000 QPS → 需总核心线程数 ≈ 5000
- 若单机部署 200 个核心线程 → 需机器数 = 5000 / 200 = 25 台
✅ 公式:
所需总线程数 ≈ QPS × 平均响应时间(秒)
机器数 = 总线程数 / 单机核心线程数
2. 拒绝策略选择
- 默认:AbortPolicy(抛异常)
- 不丢任务:使用 CallerRunsPolicy(由提交线程自己执行)
- 自定义策略:可落库、发 MQ、记录日志等。
3. 高性能队列设计
- 避免有锁队列(如 LinkedBlockingQueue)。
- 推荐无锁队列:Disruptor(环形缓冲区 + 内存预加载 + 无锁 CAS)。
六、总结与面试建议
| 线程基础 | start vs run、ThreadLocal 泄漏 | 强调 JVM 行为与内存结构 |
| 原子操作 | volatile 原子性、LongAdder 优势 | 明确 volatile 局限,LongAdder 分段思想 |
| 锁机制 | wait 在 while 中、Synchronized 优化 | 虚假唤醒、锁升级、自旋 |
| 并发容器 | HashMap 不安全、COW 原理 | 扩容死链、读写分离、弱一致性 |
| 线程池 | QPS 与线程数计算、拒绝策略 | 公式推导、CallerRunsPolicy |
💡 终极建议:面试时不仅要答出“是什么”,更要说明“为什么”和“怎么用”。结合业务场景(如秒杀、日志收集)展示架构思维,将大幅提升竞争力。



