英文:
Google Guava cache calling load method every time even if the key exists
问题
我正在尝试使用Guava Cache [版本29.0-jre],结合Guice使用,如下所示:
我的观察是,即使缓存中已存在键,Guava缓存每次都调用load方法。为什么会发生这种情况?
在上面的调试控制台中,我们可以观察到键[uuid]和值[json对象]已经存在于缓存中。然而,在下一次的获取请求中,控制流仍然进入load方法。
另一个观察结果是,我尝试了多次,可以看到具有相同键的条目多次加载到缓存中。
英文:
I am trying to use Guava Cache [version 29.0-jre] as with Guice as follows:
My observation is, Guava cache is calling the load method every time even when the key exists in the cache. Why is this happening?
In the above debug console we can observe that the key [uuid] and value [json object] are already present in the cache. However, on the next get request the control still goes inside load method.
Another observation is, I tried multiple attempts and can see entries with the same key getting loaded multiple times in the cache.
答案1
得分: 1
> 我们可以观察到关键字 [uuid]
这是你的错误。那不是关键字。你自己说过:在你的CacheBuilder设置中使用了.weakKeys()
。关键字不是UUID,而是代表它的对象的标识。
根据CacheBuilder文档:
> 注意:默认情况下,返回的缓存使用相等比较(equals方法)来确定键或值的相等性。但是,如果指定了weakKeys()
,缓存会改为使用标识(==)比较键。同样,如果指定了weakValues()
或softValues()
,缓存会对值使用标识比较。
因此,关键字不是你看到的UUID。它是该UUID对象的字面对象标识。让我用一个例子来解释。想象一下,你的缓存有String键。
// 没有 .weakKey:
String a = new String("Hello");
String b = new String("Hello");
// 这两个是相同的关键字。
// 使用 .weakKey:
String a = new String("Hello");
String b = new String("Hello");
// 这两个不是相同的关键字,因为...
a == b; // 这是 false。因此,.weakKeys() 缓存认为它们不相等。
a.equals(b); // 这是 true。因此,强键缓存认为它们相等。
你似乎想要"对于标识使用equals"这一方面,以及"但不妨碍垃圾回收"这一方面。我不知道是否有一种简单的方法来同时实现这两个目标。
英文:
> we can observe that the key [uuid]
There's your error. That's not the key. You said it yourself: .weakKeys()
is in your CacheBuilder setup. The key isn't the UUID, it's the identity of the object representing it.
From the CacheBuilder docs:
> Note: by default, the returned cache uses equality comparisons (the equals method) to determine equality for keys or values. However, if weakKeys() was specified, the cache uses identity (==) comparisons instead for keys. Likewise, if weakValues() or softValues() was specified, the cache uses identity comparisons for values.
Thus, the key is not the UUID you're seeing. It's the literal object identity of that UUID object. Let me try to explain with an example. Imagine your cache had String keys.
// Without .weakKey:
String a = new String("Hello");
String b = new String("Hello");
are the same key.
// With .weakKey THEY ARE NOT, because..
a == b; // this is false. Thus, .weakKeys() cache says not equal.
a.equals(b); // this is true. Thus, strong keys cache says equal.
You seem to want both the 'use .equals for identity' aspect, as well as '... but don't impede garbage collection' aspect. I'm not aware of an easy way to get that.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论