gpt4 book ai didi

java - 使用键和值的软引用实现缓存

转载 作者:太空宇宙 更新时间:2023-11-04 06:34:06 24 4
gpt4 key购买 nike

我想实现一个缓存,其键和值都是软引用,因为它将包含的实例可能需要很长时间才能计算(尤其是值),并且我希望包含未引用对象作为键或值的条目当且仅当我可能耗尽内存时才被垃圾收集。如果我对这些值使用弱引用,那么一旦它们没有被引用,它们就会被垃圾收集,这不是我想要做的。

一开始我用this example 。它可以工作,但是为每个缓存实例创建一个线程让我很烦恼,它对键使用强引用,并且在缓存类的某些方法调用中自行删除过时的条目(例如 WeakHashMap),当我不调用它们时,我可能会耗尽内存,这显然不起作用。我想使用 Guava,但 MapMaker 不再允许使用软键,这是合乎逻辑的,因为默认等价基于相等 (==) 而不是基于 equals() 方法,这意味着不可能重新创建相同的键。不过,我同意sebastien-lorber's comment :

i think soft keys would make sense if Guava was overriding equals method of the SoftReference. I've seen that Guava uses an "equivalence mecanism" and i think, for soft references, the defaultEquivalence should not be identity but equals, to handle such a case.

我也研究了 MapDB 和 JCS。

如何修改我上面引用的例子或者使用Guava做基于软引用的缓存,最好使用equals()而不是==来判断键的相等性?

最佳答案

我想唯一完美的解决方案就是拥有 CacheBuilder.softKeysDelegatingEquals按照您的建议,在 Guava 中。

跳到最后以获得更好的想法

也许这个解决方法可以:

  • 每当您在 Cache 中放入某些内容时,放一个新的SoftReference<Key>进入你自己的HashSet .
  • 添加removalListenerCache并删除 SoftReference来自您的HashSet

无论如何,你不需要线程。

第二部分有点棘手,因为你得到了 Key并需要删除其对应的软引用。为此,您可以将集合替换为 WeakHashMap<Key, SoftReference<Key> ,或者通过让您的 key 为 equals 来进行黑客攻击。引用:

class Key {
Key(Somedata somedata) {
this.somedata = somedata;
}

@Override public int hashCode() {
return somedata.hashCode();
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj instanceof Key) {
return somedata.equals(((Key) obj).somedata);
}
if (obj instanceof KeySoftReference) {
return equals(((KeySoftReference) obj).get());
}
return false;
}

@NonNull private final Somedata somedata;
}

// Hacky, never use for anything else.
class KeySoftReference extends SoftReference<Key> {
protected KeySoftReference(Key key) {
super(key);
this.hashCode = key.hashCode();
}

@Override public int hashCode() {
return hashCode;
}

@Override public boolean equals(Object obj) {
if (this == obj) return true;
if (obj instanceof Key) {
return ((Key) obj).equals(this);
}
if (obj instanceof KeySoftReference) {
Key key = get();
// This makes no two cleared reference equal to each other,
// That's OK as long as you never create two references to the same object.
return key!=null && key.equals(((KeySoftReference) obj).get());
}
return false;
}

private final int hashCode;
}

我想,这满足了契约(Contract),但正如我所说,它是 hacky 且未经测试的。

更新

有一个简单的解决方案。使用

CacheBuilder.weakKeys().softValues()

并添加 SoftReference<Key>给您Value 。这使得 key 可以轻松触及。

如果你真的需要比较是平等的,那么你可能不走运,尽管 WeakInterner<Key>可以提供帮助。

关于java - 使用键和值的软引用实现缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25666925/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com