--- title: "06-并发高频面试题" created: 2026-09-01 tags: - Java --- # 并发高频面试题 > [!note] 本篇定位 > 并发块收官:18 题速刷,按主题分组,每题给"一句话要点 + 展开方向",详细原理指路对应篇目。面试节奏建议:先答一句话要点,面试官追问再展开——比一口气背全文好。 ## 线程基础(3 题) **Q1:创建线程有几种方式?哪种好?** 四种:继承 Thread / Runnable / Callable+FutureTask / 线程池。推荐 Runnable+线程池:任务与执行解耦、单继承不占位、线程可复用。→ [[01-线程基础与生命周期|01-线程基础]] **Q2:sleep 和 wait 的区别?** sleep 是 Thread 静态方法、**抱着锁睡**、时间到自动醒;wait 是 Object 方法、必须先持锁、**调用后释放锁**、靠 notify 唤醒。 **Q3:怎么安全地停止一个线程?** 中断协作式:`interrupt()` 置标志 + 循环检查 `isInterrupted()` 或捕获 `InterruptedException` 优雅退出。stop() 已废弃。→ [[01-线程基础与生命周期|01-线程基础]] ## synchronized 与 volatile(5 题) **Q4:synchronized 锁的是什么?** 对象:实例方法锁 this、静态方法锁 Class 对象、代码块锁指定对象。互斥的本质是抢对象的 monitor。 **Q5:锁升级过程?** 无锁 → 偏向锁(单线程复用,新版本已移除)→ 轻量级锁(CAS 自旋,交替竞争)→ 重量级锁(OS mutex,阻塞挂起)。单向升级。→ [[02-synchronized与volatile|02-synchronized与volatile]] **Q6:volatile 能替代锁吗?** 不能。volatile 保证可见性+有序性,**不保证原子性**(i++ 仍会丢更新);只适合一写多读的状态标志。 **Q7:DCL 单例为什么要加 volatile?** `new Singleton()` 三步可能重排为"赋值引用→初始化",另一线程会拿到半成品实例。volatile 禁止该重排序。 **Q8:什么是 happens-before?** JMM 的偏序规则:A happens-before B 则 A 的结果对 B 可见。程序顺序/锁/volatile/线程启动终止规则……面试答出"volatile 写 hb 后续读、锁释放 hb 后续加锁"即可。→ [[04-JMM与内存可见性|JMM 篇]] ## 线程池(4 题) **Q9:核心参数七个?** corePoolSize / maximumPoolSize / keepAliveTime / unit / workQueue / threadFactory / handler。 **Q10:任务提交的执行顺序?** 核心线程未满先建核心线程 → 满了先**入队** → 队列满才建临时线程 → 都满走拒绝策略。(先排队后扩容,最反直觉的点) **Q11:为什么禁用 Executors?** newFixedThreadPool/newSingleThreadExecutor 用**无界队列**会堆积 OOM;newCachedThreadPool 线程数上限 Integer.MAX_VALUE 会无限涨。→ [[03-线程池|03-线程池]] **Q12:线程数怎么定?** CPU 密集 ≈ N+1;IO 密集 ≈ N×(1+等待/计算),按 2N 起步压测。依据是让 CPU 利用率打满又不至于上下文切换开销过大。 ## Lock 与 JUC(3 题) **Q13:ReentrantLock 比 synchronized 多什么?** 公平锁可选、lockInterruptibly 可中断、tryLock 超时、**多个 Condition 精准唤醒**。代价:必须手动 unlock 放 finally。 **Q14:AQS 原理?** volatile int state(含义子类定义)+ CLH 双向队列。抢锁 CAS 改 state,失败入队 park;释放时唤醒队首。独占(ReentrantLock)/共享(CountDownLatch/Semaphore)两种模式。→ [[04-Lock与AQS|04-Lock与AQS]] **Q15:CountDownLatch 和 CyclicBarrier 区别?** Latch 一次性倒数(等 N 件事完成);Barrier 可重复(凑 N 个人再一起走)。 ## 并发容器与 ThreadLocal(3 题) **Q16:ConcurrentHashMap 1.8 怎么保证线程安全?** 空槽 CAS 插入 + 非空槽 synchronized 锁头节点(锁粒度=桶);size 用 CounterCell 分散计数,**近似值**;不允许 null(get 返回 null 有歧义)。→ [[05-并发容器与工具类|05-并发容器与工具类]] **Q17:ThreadLocal 为什么会内存泄漏?** ThreadLocalMap 的 key 是弱引用会被回收,但 value 被 Thread 强引用——线程池线程不死,value 清不掉。**必须 finally 里 remove()**。 **Q18:CAS 有什么问题?** 自旋耗 CPU、只能单变量、ABA 问题(AtomicStampedReference 版本号解决)。 --- ⬅️ [[05-并发容器与工具类|05-并发容器与工具类]] 🏠 [[00-Java|00-Java]] ➡️ [[00-Spring总览|00-Spring总览]]