并发面试题
1. synchronized 和 Lock 的区别?
| 特性 | synchronized | Lock |
|---|---|---|
| 实现 | JVM 层面,关键字 | JDK 层面,接口 |
| 锁释放 | 自动释放 | 必须手动 unlock |
| 可中断 | 不可中断 | 可中断(lockInterruptibly) |
| 公平锁 | 非公平 | 支持公平和非公平 |
| 条件变量 | 不支持 | 支持多条件(Condition) |
| 尝试获取 | 不支持 | 支持 tryLock |
2. synchronized 锁升级过程?
JDK 1.6 后引入了锁升级机制,减少锁操作的开销:
无锁 → 偏向锁 → 轻量级锁 → 重量级锁- 偏向锁:单线程访问时,在对象头记录线程 ID,下次直接获取
- 轻量级锁:多线程竞争时,通过 CAS 自旋获取锁
- 重量级锁:自旋失败后,膨胀为重量级锁,线程阻塞
3. volatile 的作用和原理?
作用:
- 保证变量对所有线程的可见性
- 禁止指令重排序(内存屏障)
原理:volatile 修饰的变量在写操作后会插入写屏障(StoreStore + StoreLoad),读操作前会插入读屏障(LoadLoad + LoadStore),保证可见性和有序性。
注意:volatile 不保证原子性,如 i++ 操作不是原子的。
4. 线程池的核心参数和执行流程?
7 个核心参数:corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。
执行流程:
- 核心线程未满 → 创建核心线程执行
- 核心线程已满 → 任务入队
- 队列已满 → 创建非核心线程执行
- 线程数达最大 → 拒绝策略处理
5. CAS 是什么?有什么问题?
CAS(Compare And Swap):比较并交换,是一种无锁并发算法,通过 CPU 原子指令实现。
三大问题:
- ABA 问题:A→B→A,CAS 无法感知。解决:AtomicStampedReference 加版本号
- 循环时间长开销大:CAS 失败会一直自旋重试
- 只能保证一个共享变量的原子操作:AtomicReference 可解决