Caffeine - Caches - FAQ

常见问题

固定条目

固定条目是不能被剔除策略移除的条目。这在条目是状态资源时比较有用,比如锁,它只有在客户端使用完毕后才能被丢弃。在这种情况下剔除条目或者重新计算都将导致资源泄露。

通过使用权重并将条目评估为零权重的方式,可以将条目排除在最大容量剔除范围外。这样,该条目不会计入总容量并且会被最大容量剔除忽略。必须定义一个用以评估该条目是否是固定条目的Weighter。

通过设置持续时间为Long.MAX_VALUE或大约300年,可以将条目从过期中排出。必须定义一个用以评估该条目是否是固定条目的Expiry。

权重和有效期是在条目写入缓存是被评估的。它通过cache.asMap().compute设置或取消固定条目。

递归计算

在原子操作内部执行加载、计算或回调可能不会加入缓存。ConcurrentHashMap不允许进行这些递归操作,并且可能导致活锁(Java 8)或IllegalStateException(Java 9)。

一个替代方案是执行异步计算,比如使用AsyncLoadingCache。在这种情形下映射创建完毕后,其值为CompletableFuture,计算将在缓存的原子操作外执行。但在发生了无序的依赖链,或执行器用尽了线程池的情况下,仍有可能发生死锁。为了最大程度的减少这种情形,应该在Caffeine.executor上设置一个Executors.newCachedThreadPool()。

写冲突

Caffeine可能遭受竞争的一种情形是,当前正计算的条目数量等于或大于缓存已经包含的条目的最大数量。与之对应的是,当前计算的条目已经接近底层ConcurrentHashMap的总容量,这将阻止map大小的调整直到加载功能完成。

这种情况预期发生在缓存预热过程中(尽管可能根本不会发生)。正在计算的数量与缓存的容量相近的情形在小缓存中更加普遍。如果你正在观察基于类似问题的竞争(表现为执行不同请求的多个线程阻塞在ConcurrentHashMap的同一锁上),请考虑将容器的初始容量增大到预期的最大并发量来进行补偿,或者使用异步缓存。

ConcurrentHashMap的内部文档中介绍了一个很好的经验法则,

在随机哈希下,两个线程访问不同元素时锁竞争的概率约为 1/(8 * 元素数)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值