我将ConcurrentLinkedHashMap用作LRUCache
,我很好奇它在键的.get
之后如何处理deletion
(因为由于其政策,我们最终将不得不从LRUCache
删除密钥。
entityLRUCache = new ConcurrentLinkedHashMap.Builder<GUID, Entity>()
.maximumWeightedCapacity(100)
.build();
...
Entity getEntity(GUID entityId)
{
if (entityLRUCache.containsKey(entityId))
{
// Question: what if key gets deleted from other
// thread (when we jumped into this if statement)
// and then we'll try to retrieve it here using .get()
return entityLRUCache.get(entityId);
}
else
{
Entity entity = longLoadFromDatabase(entityId);
entityLRUCache.put(entityId, entity);
return entity;
}
}
如何使用此
ConcurrentLinkedHashMap
类处理此类情况?谢谢
最佳答案
在这种情况下,您可能希望避免多次从缓存中读取数据以避免竞争情况。相反,您可以这样写:
Entity getEntity(GUID entityId) {
Entity entity = entityLRUCache.get(entityId);
if (entity == null) {
entity = longLoadFromDatabase(entityId);
entityLRUCache.put(entityId, entity);
}
return entity;
}
加载要填充未命中的值时,这有一个竞赛,称为缓存踩踏事件。对于该库,如果有问题,可以使用锁定条带化或存储Future来编写装饰器,以避免这种情况。 Google Code Wiki过去提供了有关如何编写SelfPopulatingMap的示例。
ConcurrentLinkedHashMap
合并为番石榴,并演变为Caffeine。您应该选择该库,您可以在其中编写为Entity getEntity(GUID entityId) {
return entityCache.get(entityId, this::longLoadFromDatabase);
}
关于java - ConcurrentLinkedHashMap.Builder如何处理删除并获取?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50078766/