【问题标题】:Guava CacheBuilder not working as expectedGuava CacheBuilder 未按预期工作
【发布时间】:2016-05-28 23:56:07
【问题描述】:

嗨,我是 google guava 收藏的新手,所以我需要收藏会过期一段时间。所以我写了以下代码,但过期后没有删除数据。谁能告诉我代码的问题是什么。

Cache<String, Object> cache = CacheBuilder.newBuilder()
                .expireAfterAccess(2, TimeUnit.MILLISECONDS)
                .build();
        Object object = new Object();            
        cache.put(object.getId(), object);
        System.out.println("size :" + cache.size());
        Thread.sleep(50000);
        System.out.println("After Size :" + cache.size());

我需要将对象添加到地图中,并且在过期时间段后它将从地图中删除。但是上面的代码在线程之前和之前的代码中包含地图中的对象。

【问题讨论】:

    标签: java dictionary collections guava


    【解决方案1】:

    expireAfterAccess 的 javadoc 声明:

    过期的条目可能会被计入Cache.size(),但永远不会对读取或写入操作可见。过期条目将作为 javadoc 类中描述的日常维护的一部分进行清理。

    这意味着即使条目以.size() 计数,它们在任何其他操作中都不会可见。

    这些无效条目将被自动删除。根据 javadoc,这发生在以下情况:

    • 使用 get 访问条目:
      地图看到条目已过时并直接将其删除。
    • 偶尔缓存访问:
      有时访问.get()方法会触发内部清理,javadoc没有为此定义任何时间段。
    • 手动调用Cache.cleanUp()
      这会直接触发清理例程并删除所有过时的条目。

    Github Wiki of the cache class似乎解释了更多信息。

    如果您想在删除条目时引起注意,可以使用RemovalListener。您可以使用 .removalListener(...) 在缓存构建器上设置此侦听器。

    【讨论】:

    • 嗨,感谢您的回复。还有一件事我想知道如何从缓存映射中读取值并写入缓存映射。这与我们在标准 java 映射中的操作方式相同吗?
    • 当我在 thred sleep 之前添加 cache.getIfPresent("123") 时,它将返回 null 值。而“123”是我添加的对象的键。
    • 对不起伙计,这是我的错误。感谢您的帮助。
    • 回复评论 1: 使用 .get().put() 等标准操作可以使用缓存,但使用 build(CacheLoader) 构建 Cache 更强大,因为LoadingCache 将自动在缓存中创建该值,如果它不存在。 回复评论 2: 2 毫秒是一个很短的超时时间,内部代码可能会在调用获取代码之前超时。回复评论 3: 没问题,每个人都会出错。
    • 谢谢这是我犯的错误。上面是对象完全从内存中删除或仍在内存中。如果无法访问但它在内存中,如何从内存中删除对象。
    猜你喜欢
    • 1970-01-01
    • 2021-06-04
    • 2022-01-24
    • 2015-05-11
    • 2020-05-15
    • 2014-10-31
    • 2018-02-12
    • 2014-01-20
    • 2015-01-13
    相关资源
    最近更新 更多