使用Future实现缓存过期

时间:2012-08-15 05:48:43

标签: java multithreading concurrency

我正在尝试扩展“实践中的并发”(Brian Goetz)一书中给出的缓存实现。

我想扩展缓存,如果在10秒内没有访问任何条目,那么它应该过期。即从缓存中删除。

为此,我将Future和FutureTask扩展如下

package examples.cache;

import java.util.concurrent.Future;

public interface FutureWithExpire<V> extends Future<V> {
    public boolean isResultExpired();
}

package examples.cache;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class FutureTaskWithExpire<V> extends FutureTask<V> implements FutureWithExpire<V>{
    private final static long validPeriod = 10 * 1000;
    private long expirationTime;

    public FutureTaskWithExpire(Callable<V> callable) {
        super(callable);
    }

    @Override
    public V get() throws InterruptedException,ExecutionException{
        V v = super.get();
        expirationTime = System.currentTimeMillis() + validPeriod;
        return v;
    }

    public boolean isResultExpired(){
    if(isDone()){
        if(expirationTime < System.currentTimeMillis()){
        return true;
        }
    }
    return false;
    }
}

如上所示,我重写了get方法来计算到期时间。

在主缓存Class Memorizer中,我将启动一个新线程,它将定期扫描条目并删除isResultExpired返回true的条目。

我只是想知道这个实现是否有效或者我的代码中有一些错误?

注意我也应该覆盖get with Timeout。但是,为了保持简洁,我省略了它。

2 个答案:

答案 0 :(得分:1)

而Ofcourse expirationTime应该是易变的

答案 1 :(得分:0)

为什么这段代码:

 expirationTime = System.currentTimeMillis() + validPeriod;
在get方法中

?在我看来它应该在构造函数中,否则它可能会以太快的方式失效。假设您创建了 FutureTaskWithExpire 实例和其他一些Thread,假设无效条目的那个调用isResultExpired方法,到期时间实际上为零,因此该条目将失效,即使它仍然是有时间。

另外我认为get和isExpired的调用应该在ReentrantLock上同步,因为你不希望某些Thread使你的条目无效,而在另一个Thread中你试图给这个条目。

相关问题