**线程安全(Thread Safety)**指的是:在多线程环境下,多个线程同时访问某个代码/数据时,程序的行为仍然正确、符合预期。
下面从 原理 → 常见手段 → 实践建议 系统说明。
线程安全问题的核心原因通常有三个:
竞态条件(Race Condition)
原子性问题
可见性问题
一句话总结:
- 要么 不共享
- 要么 共享但不可变
- 要么 共享且可变,但正确同步
没有共享数据 = 天然线程安全
class Service {
public int add(int a, int b) {
return a + b;
}
}
✅ 不依赖任何成员变量
✅ 无锁、性能最好
对象一旦创建就不能修改
final class User {
private final String name;
User(String name) {
this.name = name;
}
}
✅ 多线程只读
✅ 不需要锁
✅ 如:String、Integer
⚠️ 所有字段必须是 final
同一时间只允许一个线程执行
synchronized (lock) {
count++;
}
或使用 Lock:
Lock lock = new ReentrantLock();
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
✅ 解决 原子性 + 有序性 + 可见性
⚠️ 锁粒度要合理,避免死锁
很多同步问题,标准库已经解决:
| 场景 | 推荐 |
|---|---|
| 计数 | AtomicInteger |
| 缓存 | ConcurrentHashMap |
| 队列 | BlockingQueue |
| 限流 | Semaphore |
| 等待/通知 | Condition |
AtomicInteger count = new AtomicInteger(0);
count.incrementAndGet();
✅ 无锁或轻量级锁
✅ 性能优于 synchronized
数据只在单个线程内使用
ThreadLocal ✅ThreadLocal<Integer> local = ThreadLocal.withInitial(() -> 0);
✅ 常用于:
⚠️ 注意内存泄漏问题
保证可见性和禁止重排序
volatile boolean flag = false;
✅ 适合:
❌ 不能保证原子性
volatile int count;
count++; // ❌ 仍然不是线程安全
count++; // 非原子操作
synchronized (new Object()) { ... } // 每次都是新锁
synchronized (this) { ... } // 范围太大
可以记住这个优先级:
无状态 > 不可变 > 线程封闭 > 并发容器/原子类 > 锁
判断流程:
线程安全不是“加锁”这么简单,而是:
- 减少共享
- 减少可变性
- 正确使用同步工具
如果你愿意,可以告诉我:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。