1

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不同的线程上进行调用吗?据我所知,这是一个同步调用,但我不确定。

4

2 回答 2

6

Here's a simple test allowing to know:

    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");

Output:

Thread.currentThread() = Thread[main,5,main]
Thread.currentThread() = Thread[main,5,main]

Of course, as the documentation indicates, if another thread has already started loading the value for the key, the current thread won't reload it: it will wait for the value to be loaded by the other one:

If another call to get(K) or getUnchecked(K) is currently loading the value for key, simply waits for that thread to finish and returns its loaded value.

于 2015-10-25T12:34:00.787 回答
1

要添加到 JB Nizet 的答案,您可以在此处了解为什么 Guava 避免默认使缓存成为多线程:

原因如下:如果我们想连续进行Cache维护,就需要创建一个线程,它的操作会和用户操作竞争共享锁。此外,某些环境会限制线程的创建,这会使 CacheBuilder 在该环境中无法使用。

于 2021-07-06T04:42:46.507 回答