使用定时过期时番石榴缓存在 x timeunit 后不会过期

Guava Cache not expiring after x timeunit when using timed expire

我遇到了一个问题,我的番石榴缓存没有过期。我会在下面留下我的代码。缓存仅在我再次写入缓存时过期。但是从我从关于定时过期的 javadocs 中得到的是,它应该在写入后过期 x timeunit。任何帮助将不胜感激。

    private static final Cache<UUID, RainbowWrapper> RAINBOWS = CacheBuilder.newBuilder()
        .removalListener(new RemovalListener<UUID, RainbowWrapper>() {
            @Override
            public void onRemoval(RemovalNotification<UUID, RainbowWrapper> notification) {
                CoreAPI.debug("Removing rainbow: " + notification.getKey().toString());
                RainbowWrapper wrapper = notification.getValue();
                for (UUID uuid : wrapper.getUuids()) {
                    CoreAPI.debug("Removing entity: " + uuid);
                    Bukkit.getWorlds().get(0).getEntitiesByClasses(Item.class, ArmorStand.class).stream()
                            .filter(entity -> entity.getUniqueId().equals(uuid))
                            .forEach(org.bukkit.entity.Entity::remove);
                }
            }
        }).expireAfterWrite(FADE_TIME, TimeUnit.SECONDS).build();

When does Cleanup happen?

下的 Guava wiki 对此进行了解释

基本上,只要您不调用缓存的任何方法,就什么都不会发生,因为如果不为缓存创建自己的线程是不可能的,这通常是不希望的,因此不会自动完成番石榴缓存。

如果您只有对缓存的读取访问权限,则调用移除侦听器也可能需要一段时间,因为 Guava 假定对缓存的读取访问应该很快,因此尽量少做工作尽可能读访问,这意味着它通常不调用删除侦听器。只有在一段时间内没有写入访问时,缓存才会在读取访问时进行清理并调用移除侦听器。

请注意,这仍然意味着过期功能正在运行:过期条目不会从任何缓存方法返回。删除侦听器的调用时间可能比您预期的要晚。

如果您想强制及时删除通知,您应该定期调用 Cache.cleanUp()(例如,从一个单独的线程)。

如果在时间结束后尽快收到通知对您很重要,我会简单地使用 ScheduledExecutorService 并向其提交任务,而不是依赖缓存及其删除通知。