gpt4 book ai didi

java - 如何使用 Guava 的 LoadingCache 更新存储在缓存中的 LinkedList 值

转载 作者:行者123 更新时间:2023-11-29 05:13:53 26 4
gpt4 key购买 nike

我正在尝试利用 Guava 库中的 LoadingCache 来缓存 LinkedList

LoadingCache<Integer, LinkedList<String>> cache;

我已经设置了一个 CacheLoader 来处理未命中,它工作正常。然而,还有另一个系统需要提交对现有缓存条目的更新。每个更新都需要附加到 LinkedList 并且会以相当快的速度(每分钟数千次)到达。最后,它需要是线程安全的。

这是一个说明逻辑但不是线程安全的天真的方法:

public void add(Integer key, String value) {
LinkedList<String> list = cache.get(key);
list.add(value);
cache.put(key, list);
}

关于如何使这项工作有任何建议吗?我可以查看其他库,但 Guava 14 已经是此代码库的依赖项,并且会非常方便。

最佳答案

最后一行

public void add(Integer key, String value) {
LinkedList<String> list = cache.get(key);
list.add(value);
cache.put(key, list);
}

不需要,因为您已经修改了从缓存中获取的对象。也许你需要的只是

public void add(Integer key, String value) {
LinkedList<String> list = cache.get(key);
synchronized (list) {
list.add(value);
}
}

这取决于发生什么驱逐。如果根本没有驱逐,那么它将起作用。如果一个条目可以在更新方法完成之前被逐出,那么你就不走运了。

不过,有一个简单的解决方案:使用全局锁会起作用,但显然效率很低。所以使用锁列表:

private static final CONCURRENCY_LEVEL = 64; // must be power of two
List<Object> locks = Lists.newArrayList(); // an array would do as well
for (int i=0; i<CONCURRENCY_LEVEL; ++i) locks.add(new Object());

public void add(Integer key, String value) {
synchronized (locks.get(hash(key))) {
cache.get(key).add(value);
}
}

hash - 取决于 key 的分布 - 可以像 key.intValue() & (CONCURRENCY_LEVEL-1) 或类似 here 的东西一样简单什么样的随机分布。


虽然我上面的锁列表应该可以工作,但 Guava 中有 Striped.lock(int),这使它更简单一些并负责填充(参见 false sharing 了解它的好处) ) 等等。


您很可能不应该使用 LinkedList,因为它几乎总是比 ArrayList 慢。

关于java - 如何使用 Guava 的 LoadingCache 更新存储在缓存中的 LinkedList 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27284164/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com