缓存自动过期的项目

时间:2013-04-09 19:48:13

标签: java guava

Java,Guava或其他库中是否有可用于执行以下操作的缓存实现:

  • 键,值缓存,自动过期的项目。修改该值会重新启动到期计时器。每个键/值对分别到期(有自己的计时器)。
  • 可以手动添加项目,例如cache.put(key, value);

我见过Guava LoadingCache,但该实现要求您实现load(key)方法。 load(key)方法旨在通过使用数据库或其他资源来计算基于密钥的值。一旦通过load(key)方法计算该值,我相信LoadingCache将结果(键,值)对粘贴在缓存中。

我的实现要求与LoadingCache不同,因为我的密钥将保持不变,但相应的值将在我刮取数据库时慢慢更新。换句话说,我不想像LoadCache在load(key)方法中那样立即加载整个值 - 我想保持密钥相同并逐步更新值Object,具体取决于我从数据库。因此,这似乎排除了使用LoadingCache,因为load(key)方法会强制您同时加载密钥的相应值。

我想逐步加载值(对于每个键)的原因是因为它需要很长时间并且我使用AJAX轮询来保持用户更新。因此,一次加载它是没用的。我想缓存这些值,以便我可以使用AJAX轻松检索它们。我希望它们过期,因为一旦用户访问完网页,它们就没用了。

2 个答案:

答案 0 :(得分:1)

JCS支持空闲时间到期和手动添加

答案 1 :(得分:1)

按照@Louis Wasserman的建议,我实现了以下代码:

LoadingCache<String, WorkerItem> cache = CacheBuilder.newBuilder()
.concurrencyLevel(level) 
.maximumSize(size)
.expireAfterWrite(seconds, TimeUnit.SECONDS)
.removalListener(this)
.build(
    new CacheLoader<String, WorkerItem>() {
        public WorkerItem load(String key) throws Exception {
            WorkerItem workerItem = new MoreSpecificWorkerItem();
            workerItem.setTask(key);
            Controller.beginWorking(workerItem); //Runs in thread pool
            return workerItem;
        }
    }
);

当用户在Cache上调用get()时,它将立即返回WorkerItem并将在后台填充它。只要您使用WorkerItem方法或类似方法实施isFinished(),就可以知道它何时可以使用。

我实现了一个清理服务,因为缓存不会定期删除过期的项目。过期的项目只是标记为脏,并在下次访问它们或下次调用清理时被删除。

final Runnable doCleanup = new Runnable() {
    public void run() { 
        LoadingCache<K, V> cache = getCache();
        cache.cleanUp();
        }
    }

ScheduledFuture<?> cleanupHandle = scheduler.scheduleAtFixedRate(doCleanup, 1, 1, TimeUnit.MINUTES);
return cleanupHandle;