2012-08-15 44 views
4

我試圖擴展書中併發實踐中給出的緩存實現(Brian Goetz)。用未來實現緩存過期

我想擴展緩存,以便如果任何條目在10秒內未被訪問,則應該過期。即從緩存中移除。

爲此,我已經擴展和未來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的條目。

我只是想知道這個實現是否會工作,或者我的代碼中有一些錯誤?

注意我也應該覆蓋get with Timeout。但是,爲了保持簡潔,我省略了這一點。

+0

而不是使用'isResultExpired'你可以只返回'null'否則,你可以有一個競爭條件,其中isExpiredResult是假的,但通過你得到它的時候,它已經過期。 – 2012-08-15 08:09:49

+0

如果您希望某些生產代碼到期,而不僅僅是練習,則可以使用'WeakHashMap'類來評估依賴於JVM過期的緩存項目。 – 2012-08-15 20:45:40

回答

0

這是爲什麼代碼:

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

?在我看來,它應該在構造函數中,否則它可能會失效太快。假設您創建了實例和其他一些線程(假設無效條目調用isResultExpired方法)的實例,過期時間實際上爲零,因此條目將失效,即使它仍有時間存在。

另外我認爲get和isExpired的調用應該在ReentrantLock上同步,例如,因爲您不希望某個線程使您的條目失效,而在另一個線程中嘗試給出該​​條目。

+0

這就是爲什麼我使用isDone() - 所以只有在任務完成時方法纔會返回true,但是同意2個方法應該同步。 – user1599840 2012-08-15 20:22:50

1

而且Ofcourse expirationTime應該是揮發性