Google Guava Cache是​​否在同一个线程上加载?

时间:2015-10-25 10:49:45

标签: multithreading caching guava google-guava-cache

默认情况下,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的调用是否会在另一个线程上进行?据我所知,这是一个同步通话,但我不确定。

2 个答案:

答案 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 在该环境中无法使用。