默认情况下,Google Guava Cache是否会在同一个线程上加载缓存?
代码:
cache = CacheBuilder
.newBuilder()
.refreshAfterWrite(2, TimeUnit.SECONDS)
.build(new CacheLoader<String,String>() {
@Override
public String load(String s) throws Exception {
return addCache(s);
}
});
对addCache
的调用是否会在另一个线程上进行?据我所知,这是一个同步通话,但我不确定。
答案 0 :(得分:4)
这是一个简单的测试,可以让我们知道:
System.out.println("Thread.currentThread() = " + Thread.currentThread());
LoadingCache<String, String> cache = CacheBuilder
.newBuilder()
.refreshAfterWrite(2, TimeUnit.SECONDS)
.build(new CacheLoader<String, String>() {
@Override
public String load(String s) throws Exception {
System.out.println("Thread.currentThread() = " + Thread.currentThread());
return "world";
}
});
cache.get("hello");
输出:
Thread.currentThread() = Thread[main,5,main]
Thread.currentThread() = Thread[main,5,main]
当然,正如文档所示,如果另一个线程已经开始加载该键的值,则当前线程不会重新加载它:它将等待该值被另一个加载:< / p>
如果对get(K)或getUnchecked(K)的另一个调用当前正在加载key的值,则只需等待该线程完成并返回其加载的值。
答案 1 :(得分:1)
要添加到 JB Nizet 的答案中,您可以了解为什么 Guava 在默认情况下避免将缓存设为多线程here:
<块引用>这样做的原因是:如果我们想持续进行Cache维护,我们需要创建一个线程,它的操作会与用户操作争夺共享锁。此外,某些环境会限制线程的创建,这会使 CacheBuilder 在该环境中无法使用。