4

我正在尝试扩展《实践中的并发》一书(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 的条目。

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

注意我也应该用 Timeout覆盖get 。但是,为了简洁起见,我省略了这一点。

4

2 回答 2

1

当然过期时间应该是不稳定的

于 2012-08-15T20:40:11.197 回答
0

为什么是这个代码:

 expirationTime = System.currentTimeMillis() + validPeriod;

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

此外,我认为 get 和 isExpired 的调用应该在 ReentrantLock 上同步,因为您不希望某些线程使您的条目无效,而在另一个线程中您正试图提供该条目。

于 2012-08-15T07:10:01.973 回答