本文介绍一种比 synchronized 更轻量、更高性能的线程安全解决方案:利用 volatile 或 AtomicReference 取代传统的同步方法,结合不可变列表(例如 List.copyOf()),实现无锁读取与原子更新操作。
在高并发的生产环境中,频繁使用 synchronized 方法会导致显著的性能损耗和可伸缩性瓶颈。你目前的代码中,getFoo() 和 refresh() 均被 synchronized 修饰,但实际业务场景非常清晰:读取操作不涉及状态修改,写入操作仅整体替换列表——这完全符合“不可变发布”(immutable publication)模型,完全没有必要使用重量级锁。
✅ 推荐方案:volatile + 不可变列表
由于 list 始终通过整体赋值方式更新(不存在原地修改),并且所有读取操作都在赋值完成后进行,volatile 字段足以提供所需的 happens-before 保证:新列表的构建与发布,对所有线程均立即可见。
private volatile Listlist = List.of(); // 初始化为空不可变列表 public Foo getFoo(Condition condition) { // 无需同步:volatile 保证读到最新引用,且列表本身不可变 for (Foo foo : list) { if (condition.check(foo)) { return foo; } } return null; } public void refresh() { // fetchFromDB() 返回新列表;用 List.copyOf() 强制不可变 List newList = List.copyOf(fetchFromDB()); list = newList; // volatile 写入,对所有线程立即可见 }
? 注意:List.copyOf()(Java 10+)不仅会创建不可变副本,还会在运行时检查源列表是否被意外修改(抛出 UnsupportedOperationException),因此比 Collections.unmodifiableList() 更加安全可靠。
? 备选方案:AtomicReference>
如果你需要支持更复杂的原子操作(例如 CAS 更新或条件刷新),可以考虑采用 AtomicReference:
private final AtomicReference> listRef = new AtomicReference<>(List.of()); public Foo getFoo(Condition condition) { for (Foo foo : listRef.get()) { // get() 具有 volatile 读语义 if (condition.check(foo)) { return foo; } } return null; } public void refresh() { List
newList = List.copyOf(fetchFromDB()); listRef.set(newList); // set() 具有 volatile 写语义 }
⚠️ 关键注意事项
- 不可变是核心前提:list 引用所指向的对象必须不可被修改。如果 fetchFromDB() 返回的是可变 ArrayList,必须使用 List.copyOf() 或 Collections.unmodifiableList() 进行封装;否则,其他线程在遍历时可能遇到 ConcurrentModificationException 或数据不一致问题。
- 元素本身也需要线程安全:Foo 实例自身不应包含共享可变状态;如果内部存在状态,必须确保其线程安全性(例如使用 final 字段、不可变设计或同步访问机制)。
- 防范隐式修改:切勿将 list 赋值给非 final 的可变变量后再进行修改(例如 List
temp = list; temp.add(...)),这将彻底破坏线程安全性。 - 文档即契约:在字段声明旁添加明确注释:
// Thread-safe: list is volatile and always points to an unmodifiable List. // Never mutate the list or its elements after assignment. private volatile List
list = List.of();
✅ 总结
相较于 synchronized,volatile 方案彻底消除了锁竞争,显著提升了读取吞吐量;同时结合 List.copyOf() 确保不可变语义,从源头上杜绝了并发修改的风险。该模式简洁、高效、易于测试,堪称“只读+全量更新”场景的最佳实践。
