Java Cache缓存提升并发的实用指南
一、总体思路与架构选择
二、单机并发缓存的落地做法
| 方案 | 并发控制 | 过期/容量 | 适用场景 | 要点 |
|---|---|---|---|---|
| ConcurrentHashMap + computeIfAbsent | 原子“仅一次加载” | 需自行实现 | 简单 KV、计算/加载成本较高 | 代码简洁,避免重复加载 |
| ConcurrentHashMap + Future/ FutureTask | 单任务计算、其他线程等待结果 | 需自行实现 | 高并发下防止击穿 | 异常需移除 Future,避免缓存“污染” |
| Caffeine/Guava Cache | 库内并发控制 | 内置 TTL、最大容量、弱引用等 | 生产级本地缓存 | 推荐首选,减少自研成本 |
LoadingCache<String, String> cache = Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build(key -> loadFromDb(key));
String v = cache.get("k"); // 并发安全,仅一个线程触发 load
ConcurrentHashMap<String, Future<String>> cache = new ConcurrentHashMap<>();
Future<String> f = cache.get(key);
if (f == null) {
FutureTask<String> ft = new FutureTask<>(() -> loadFromDb(key));
f = cache.putIfAbsent(key, ft);
if (f == null) { f = ft; ft.run(); }
}
return f.get(); // 等待结果或抛异常
三、分布式缓存与框架集成
@Service
public class UserService {
@Cacheable(value = "user", key = "#id")
public User getById(Long id) {
return userRepository.findById(id); // 缓存未命中时执行
}
@CacheEvict(value = "user", key = "#user.id")
public void update(User user) {
userRepository.save(user); // 更新后主动失效
}
}
四、高并发下的稳定性与一致性策略
五、落地检查清单
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。