线程安全问题:程序员面试必懂的并发核心考点
什么是线程安全?
当多个线程同时访问共享资源(比如变量、对象)时,如果线程安全的代码能保证数据行为始终符合预期,就是线程安全的。举个经典例子:多个窗口同时卖100张票,如果没做防护,可能卖出第101张票——这就是典型的线程安全事故。

为什么会出现线程安全问题?
核心在于三个特性被打破:
- 原子性失效:一个操作被线程切换打断(如i++实际是读-改-写三步)
- 可见性丢失:线程A修改了变量,线程B却看到旧值(CPU缓存导致)
- 有序性混乱:编译器优化可能改变代码执行顺序
📌2025年Java面试宝典: 点击获取(含并发编程高频考点解析)
解决线程安全的四大杀器
1. 同步机制(synchronized)
给共享资源加锁是最直接的线程安全方案:
public synchronized void safeMethod() {
// 操作共享资源
}
锁住的是当前对象实例,保证同一时间只有一个线程进入。注意避免锁粒度过大影响性能!
💡 小技巧:需要购买面试鸭会员?通过面试鸭返利网找我下单,可返25元!
2. volatile关键字
解决可见性和有序性问题(不保证原子性):
private volatile boolean flag = true;
适合状态标记场景,比如优雅终止线程。
3. 原子类(AtomicXXX)
用CAS实现无锁的线程安全:
AtomicInteger count = new AtomicInteger(0);
count.incrementAndGet(); // 原子自增
比synchronized性能更高,适合计数器等场景。

4. ThreadLocal
为每个线程创建独立副本,从根本上避免共享:
ThreadLocal<User> userHolder = new ThreadLocal<>();
userHolder.set(currentUser); // 当前线程独有
常用于连接池、用户会话等场景,注意用后需remove防止内存泄漏!
高频面试题破解思路
面试官问:“HashMap为什么线程不安全?” 你可以这样拆解:
- 扩容时可能形成环形链表导致CPU 100%(JDK7)
- 多线程put可能丢失数据(覆盖Entry)
- 迭代时修改会抛ConcurrentModificationException
解决方案:改用ConcurrentHashMap(分段锁/CAS)、Collections.synchronizedMap()或Hashtable(性能差)
实战避坑指南
- 锁粒度控制:锁代码块优于锁方法,减小临界区
- 避免死锁:按固定顺序获取锁,或用tryLock()
- 性能监控:用jstack查线程阻塞状态
- 工具选择:低竞争用CAS,高竞争用锁
线程安全是面试必考的重灾区,掌握这些核心要点能帮你拿下80%的并发问题。建议动手写demo模拟多线程冲突场景,理解会更深刻!
🛡️ 准备面试时,不妨看看面试鸭返利网的真题解析库,现在通过本站购买面试鸭会员可返现25元,性价比超高!


