2013-03-07 100 views
2

爲什麼timedCachetest在最後一行失敗?爲什麼在60秒後緩存不爲空?爲什麼設置expireAfterAccess不起作用?

package com.test.cache; 

import java.util.concurrent.TimeUnit; 

import junit.framework.Assert; 

import org.junit.After; 
import org.junit.Before; 
import org.junit.Test; 

import com.google.common.cache.Cache; 
import com.google.common.cache.CacheBuilder; 

public class CacheTest { 
    private static final int MAXIMUM_SIZE = 10; 
    private static final int CONCURRENCY_LEVEL = 1; 
    private static final long EXPIRE_AFTER_ACCESS = 60; 
    Cache<String, Thing> cache; 
    private static TimeUnit unit = TimeUnit.SECONDS; 
    private static long sec = 1000; 

    @Before 
    public void setUp() throws Exception { 
     cache = CacheBuilder.newBuilder().maximumSize(MAXIMUM_SIZE).concurrencyLevel(CONCURRENCY_LEVEL).expireAfterAccess(EXPIRE_AFTER_ACCESS, unit).build(); 
    } 

    @After 
    public void tearDown() { 
     cache = null; 
    } 

    @Test 
    public void simpleCachetest() { 
     String key = "key"; 
     Integer hc = key.hashCode(); 
     Thing thing = new Thing(key); 
     cache.put(key, thing); 
     thing = cache.getIfPresent(key); 
     Assert.assertNotNull(thing); 
     Assert.assertEquals(hc, thing.getValue()); 
     Assert.assertEquals(key, thing.getName()); 
     Assert.assertEquals(1, cache.size()); 
    } 

    @Test 
    public void timedCachetest() { 
     String key = "key"; 
     Thing thing = new Thing(key); 
     Assert.assertEquals(0, cache.size()); 
     cache.put(key, thing); 
     Assert.assertEquals(1, cache.size()); 
     try { 
      thing = cache.getIfPresent(key); 
      long millis = 100 * sec; 
      Thread.sleep(millis); 
      // cache.invalidateAll(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     Assert.assertNotNull(thing); 
     Assert.assertEquals(key, thing.getName()); 
     Assert.assertEquals(0, cache.size()); 
    } 

    class Thing { 
     public Thing(String key) { 
      this.name = key; 
      this.value = key.hashCode(); 
     } 

     public String getName() { 
      return name; 
     } 

     public Integer getValue() { 
      return value; 
     } 

     private String name; 
     private Integer value; 
    } 
} 

回答

9

它說那裏的CacheBuilder的Javadoc:

如果expireAfterWrite或expireAfterAccess要求的條目可以在每個高速緩存的修改被驅逐,在偶爾的高速緩存訪​​問,或到Cache.cleanUp電話( )。過期的條目可能會在Cache.size()中計數,但對於讀取或寫入操作永遠不可見。

CacheBuilder緩存做保養或者當它的特別要求,或者當它可以這樣做,作爲一個高速緩存突變的一部分,或者偶爾上讀取。它不會例如啓動一個線程來執行緩存維護,因爲a)線程相對較重,並且b)某些環境限制了線程的創建。

+3

感謝您閱讀本手冊。 ;)也許我應該刪除這個問題。 – hash 2013-03-08 00:02:45

相關問題