并发多线程
大约 5 分钟
阅读提示
建议按“线程基础 -> 并发三特性 -> 锁与 AQS -> 线程池 -> 线上排障”顺序复习。
面试回答时尽量带一个真实场景(如高并发下延迟抖动、线程池打满、锁竞争)。
推荐训练法
- 先过题目清单,确认知识覆盖面。
- 每题先用 20~40 秒口述结论,再补机制细节。
- 对高频题(CAS、synchronized、线程池)做二次复述。
1、什么是进程、线程、协程?
回答提示:
- 进程是资源分配单位,线程是 CPU 调度单位。
- 协程是用户态轻量执行单元,切换成本更低。
参考回答:
- 一个进程可包含多个线程,线程共享进程资源但执行路径独立。
- 协程常用于高并发 IO 场景,通过用户态调度减少线程切换开销。
2、线程状态有哪些?
回答提示:
- Java 线程状态:
NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。
参考回答:
- 重点理解
BLOCKED(等锁)和WAITING/TIMED_WAITING(主动等待)差异。
3、创建线程有哪些方式?
- 继承
Thread。 - 实现
Runnable。 - 实现
Callable+Future。 - 使用线程池
ExecutorService(生产最常用)。
4、并发三大特性是什么?
回答提示:
- 原子性:操作不可分割。
- 可见性:线程间可立即看到更新。
- 有序性:程序执行顺序受约束。
参考回答:
synchronized可保证原子性和可见性;volatile保证可见性并约束重排序。
5、什么是 CAS?优缺点是什么?
回答提示:
- CAS:比较并交换,原子指令,常用于无锁并发。
- 优点:避免阻塞,吞吐高。
- 缺点:ABA 问题、自旋开销大、只适合单变量原子更新。
参考回答:
- CAS 失败会重试,竞争激烈时 CPU 空转明显,必要时要退回锁方案。
6、什么是 ABA 问题?如何解决?
回答提示:
- 值从 A -> B -> A,CAS 看起来没变但过程已变。
- 可用版本号机制解决,如
AtomicStampedReference。
7、synchronized 的底层和使用范围
回答提示:
- 修饰实例方法:锁对象实例。
- 修饰静态方法:锁 Class 对象。
- 修饰代码块:锁指定对象。
参考回答:
synchronized是可重入、独占锁,JDK 之后通过偏向锁/轻量级锁做过优化。
8、volatile 能保证什么?不能保证什么?
回答提示:
- 能保证可见性和一定有序性。
- 不能保证复合操作原子性(如
count++)。
9、ReentrantLock 和 synchronized 有什么区别?
ReentrantLock支持可中断加锁、超时尝试、公平锁。synchronized语法简单,JVM 层优化充分。- 复杂并发控制(多条件队列)更适合
ReentrantLock。
10、什么是 AQS?
回答提示:
- AQS(AbstractQueuedSynchronizer)是并发同步框架核心。
- 通过
state+ CLH 队列实现锁和同步器。
参考回答:
ReentrantLock、Semaphore、CountDownLatch等都基于 AQS 思路构建。
11、wait / notify / notifyAll 和 sleep 的区别
wait会释放对象锁,必须在同步块中调用。sleep不释放锁,只是让出 CPU 时间片。notify随机唤醒一个等待线程,notifyAll唤醒全部。
12、CountDownLatch、CyclicBarrier、Phaser 的区别
CountDownLatch:一次性门闩,常用于主线程等待子任务结束。CyclicBarrier:可复用屏障,常用于多线程分阶段对齐。Phaser:更灵活,支持动态注册与多阶段同步。
13、Semaphore 适合什么场景?
回答提示:
- 控制并发访问量,典型场景:限流、连接池资源保护。
14、ThreadLocal 的作用和风险
回答提示:
- 作用:线程隔离上下文(如用户信息、追踪ID)。
- 风险:在线程池中若不
remove,可能造成内存泄漏。
15、为什么要用线程池?
- 降低线程创建/销毁开销。
- 控制并发度,保护系统资源。
- 便于统一监控和治理。
16、线程池核心参数有哪些?
corePoolSizemaximumPoolSizekeepAliveTimeworkQueuethreadFactoryRejectedExecutionHandler
17、线程池拒绝策略有哪些?
AbortPolicy:直接抛异常。CallerRunsPolicy:由提交线程自己执行。DiscardOldestPolicy:丢弃最旧任务。DiscardPolicy:直接丢弃。
18、线程池参数怎么估算?
回答提示:
- CPU 密集:线程数接近 CPU 核数。
- IO 密集:线程数可适当放大(如 2N)。
参考回答:
- 实际工程要结合压测、队列积压、RT 与 CPU 使用率动态调参。
19、JMM 是什么?为什么需要它?
回答提示:
- JMM 是 Java 内存访问规则,统一不同硬件平台的并发语义。
- 解决可见性、有序性和跨平台一致性问题。
20、乐观锁和悲观锁怎么理解?
- 悲观锁:先加锁再操作,冲突场景更稳。
- 乐观锁:先操作后校验(CAS/版本号),读多写少更高效。
21、如何定位线上并发问题?
- 先看监控:线程数、CPU、队列长度、拒绝次数。
- 再看 JVM:
jstack、jcmd、GC 日志。 - 最后看代码:锁粒度、线程池配置、共享变量访问。
22、面试表达模板(可直接复述)
- 我会先判断是“计算瓶颈”还是“并发控制瓶颈”,再决定优先调线程池还是降锁竞争。
- 对线程池我会重点盯队列积压和拒绝策略,避免任务堆死。
- 对锁问题我会通过线程 dump 定位阻塞链,再做锁粒度优化或改无锁结构。
