谷歌的Guava缓存每次调用load方法,即使键已存在。

huangapple go评论82阅读模式
英文:

Google Guava cache calling load method every time even if the key exists

问题

我正在尝试使用Guava Cache [版本29.0-jre],结合Guice使用,如下所示:

谷歌的Guava缓存每次调用load方法,即使键已存在。

我的观察是,即使缓存中已存在键,Guava缓存每次都调用load方法。为什么会发生这种情况?

谷歌的Guava缓存每次调用load方法,即使键已存在。

在上面的调试控制台中,我们可以观察到键[uuid]和值[json对象]已经存在于缓存中。然而,在下一次的获取请求中,控制流仍然进入load方法。

另一个观察结果是,我尝试了多次,可以看到具有相同键的条目多次加载到缓存中。

谷歌的Guava缓存每次调用load方法,即使键已存在。

英文:

I am trying to use Guava Cache [version 29.0-jre] as with Guice as follows:

谷歌的Guava缓存每次调用load方法,即使键已存在。

My observation is, Guava cache is calling the load method every time even when the key exists in the cache. Why is this happening?

谷歌的Guava缓存每次调用load方法,即使键已存在。

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.

谷歌的Guava缓存每次调用load方法,即使键已存在。

答案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.

huangapple
  • 本文由 发表于 2020年8月18日 18:29:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63466731.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定