ConcurrentLinkedHashMap

ConcurrentLinkedHashMap

我将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/

10-12 07:36