【问题标题】:Choosing Keys for Guava Cache为 Guava 缓存选择键
【发布时间】:2014-03-12 15:03:23
【问题描述】:

我是 Guava 缓存的新手,正在寻求一些建议。

我想缓存“函数”——负责某些计算的类。每个类都有 3 个双重属性:start、max、increment

创建用于存储在缓存中的密钥的最佳方法是什么?复杂对象呢?

我正在考虑使用 Hasher,但对于复杂对象,相同的哈希并不意味着相同的对象。所以key->值不会是唯一的。

另外,Cache 是如何查找密钥的? 我注意到,如果我使用 2 个对象作为传递等于的键,缓存认为它是唯一键。它是否基于 key1 == key2 工作?

public static void testGuavaCache() {
    Cache<Object, String> CACHE = CacheBuilder.newBuilder().weakKeys().weakValues().build();

    for (int i = 0; i < 2; i++) {
        Joiner joiner = Joiner.on('|');
        String key1 = joiner.join(i, i, i, i, i, i, i);

        for (int j = 0; j < 2; j++) {
            String key = joiner.join(i, i, i, i, i, i, i);
            System.out.println(key1.equals(key));
            System.out.println(key1 == key);
            try {
                String m = CACHE.get(key, new Callable<String>() {
                    @Override
                    public String call() throws Exception {
                        return "test";
                    }
                });

                System.out.println("Size = " + CACHE.size());

            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
}

输出是:

true
false
Size = 1
true
false
Size = 2
true
false
Size = 3
true
false
Size = 4

删除weakKeys() 解决了这个问题。这是预期的吗?

【问题讨论】:

  • 创建对象真的很昂贵吗?如果没有,则忘记任何缓存并根据需要重新创建。

标签: java caching key guava


【解决方案1】:

阅读weakKeys 的文档:

警告:使用此方法时,生成的缓存将使用标识 (==) 比较来确定键的相等性。

所以是的,你应该停止使用weakKeys,而且你最好有一个合适的值对象,而不是把东西串联成一个String

【讨论】:

  • 谢谢。答案是 RTFM :)
【解决方案2】:

如果参数是字符串,请使用分隔符将所有参数连接到您的函数。这将唯一地定义结果。如果参数是数字或两者的组合,您可以将它们编码为 ByteBuffer 并使用它的 hashCode 作为键来节省内存。如果参数数据很大(可能 +32 字节),您可以使用摘要算法(如 MD5)对密钥进行编码,并将结果用作密钥。在这种情况下,您需要权衡生成摘要而不是计算缓存结果的处理成本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多