我正在尝试扩展“实践中的并发”(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。但是,为了保持简洁,我省略了它。
答案 0 :(得分:1)
而Ofcourse expirationTime应该是易变的
答案 1 :(得分:0)
为什么这段代码:
expirationTime = System.currentTimeMillis() + validPeriod;
在get方法中?在我看来它应该在构造函数中,否则它可能会以太快的方式失效。假设您创建了 FutureTaskWithExpire 实例和其他一些Thread,假设无效条目的那个调用isResultExpired方法,到期时间实际上为零,因此该条目将失效,即使它仍然是有时间。
另外我认为get和isExpired的调用应该在ReentrantLock上同步,因为你不希望某些Thread使你的条目无效,而在另一个Thread中你试图给这个条目。