我正在尝试扩展在实践中的并发( 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方法来计算过期时间。
在主缓存类中,即Memorizer,我将启动一个新线程,该线程将定期扫描条目,并删除isResultExpired返回true的条目。
我只是想知道这个实现是否可以工作,或者我的代码中是否有一些bug?
注意:我也应该覆盖get with Timeout。然而,为了保持简洁,我省略了这一点。
发布于 2012-08-16 04:40:11
当然,expirationTime应该是易失性的
发布于 2012-08-15 15:10:02
为什么这段代码是:
expirationTime = System.currentTimeMillis() + validPeriod;在get方法中?在我看来,它应该在构造函数中,否则它很快就会失效。假设您创建了FutureTaskWithExpire实例和其他一些线程,用于使条目无效的线程调用了isResultExpired方法,那么过期时间实际上将为零,因此条目将被失效,即使它仍然有活动的时间。
我还认为,对get和isExpired的调用应该在ReentrantLock上同步,因为您不希望某些线程使您的条目无效,而在另一个线程中,您试图提供该条目。
https://stackoverflow.com/questions/11964652
复制相似问题