在 Java 中,多线程安全的核心问题是:多个线程同时访问共享资源时,可能出现数据不一致、脏读、幻读、死锁等问题。要保证线程安全,本质就是控制对共享资源的并发访问。
下面从 原理 → 常用手段 → 实践建议 系统说明。
线程不安全通常由以下三点导致(JMM 三大问题):
原子性(Atomicity)
操作被线程切换打断
i++ // 实际是 读取 → 修改 → 写回
可见性(Visibility)
一个线程修改了变量,其他线程看不到
while(!flag) { } // 可能死循环
有序性(Ordering)
指令重排序导致异常
// 双重检查锁单例问题
synchronized(最常用)// 1. 修饰方法
public synchronized void add() {
count++;
}
// 2. 修饰代码块
synchronized (this) {
count++;
}
✅ 适合:
Lock(更灵活)ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
✅ 适合:
AtomicInteger count = new AtomicInteger(0);
count.incrementAndGet();
✅ 适合:
⚠️ 注意 ABA 问题(可用 AtomicStampedReference)
| 不安全 | 安全替代 |
|---|---|
| ArrayList | CopyOnWriteArrayList |
| HashMap | ConcurrentHashMap |
| HashSet | ConcurrentHashMap.newKeySet() |
Map<String, String> map = new ConcurrentHashMap<>();
✅ 适合:
volatile(轻量同步)private volatile boolean flag = false;
❌ 不保证原子性
✅ 适合:
最好的同步是不共享
private static final String CONFIG = "stable";
ThreadLocal<Integer> local = ThreadLocal.withInitial(() -> 0);
class Counter {
int count = 0;
void add() { count++; }
}
| 方案 | 示例 |
|---|---|
| synchronized | synchronized void add() |
| Lock | ReentrantLock |
| 原子类 | AtomicInteger |
| 不变性 | 无共享状态 |
tryLockJava 多线程安全 = 控制共享 + 保证原子/可见/有序
常用武器:
synchronizedLockAtomicXXXvolatile如果你愿意,我可以:
你想从哪方面深入?
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。