Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ConcurrentLinkedHashMap.Builder如何处理删除和获取?_Java_Data Structures_Concurrency_Concurrenthashmap - Fatal编程技术网

Java ConcurrentLinkedHashMap.Builder如何处理删除和获取?

Java ConcurrentLinkedHashMap.Builder如何处理删除和获取?,java,data-structures,concurrency,concurrenthashmap,Java,Data Structures,Concurrency,Concurrenthashmap,我使用as LRUCache,我很好奇它是如何处理的。删除密钥后获取,因为由于其策略,我们最终将不得不从LRUCache中删除密钥 entityLRUCache = new ConcurrentLinkedHashMap.Builder<GUID, Entity>() .maximumWeightedCapacity(100)

我使用as LRUCache,我很好奇它是如何处理的。删除密钥后获取,因为由于其策略,我们最终将不得不从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;
}
Entity getEntity(GUID entityId) {
  return entityCache.get(entityId, this::longLoadFromDatabase);
}
当加载值以填充未命中时,这有一个称为缓存踩踏的竞争。对于该库,可以编写一个使用锁条带化或存储未来的装饰器,以避免出现问题。谷歌代码维基(GoogleCodeWiki)提供了一个如何编写代码的示例

ConcurrentLinkedHashMap合并到番石榴中,并演变为。你应该更喜欢那个图书馆,在那里你可以把它写成

Entity getEntity(GUID entityId) {
  Entity entity = entityLRUCache.get(entityId);
  if (entity == null) {
    entity = longLoadFromDatabase(entityId);
    entityLRUCache.put(entityId, entity);
  }
  return entity;
}
Entity getEntity(GUID entityId) {
  return entityCache.get(entityId, this::longLoadFromDatabase);
}

后一个选项也会有缓存踩踏吗?不,它会为您处理无锁读取,然后是每项锁以计算它。如果longLoadFromDatabase是异步的,即从RxJava返回单值,我如何能够很好地调整后一个选项?我确实找到了RxJava后面的write,但我仍然不太清楚。@AlexKokorin您考虑过AsyncLoadingCache吗?