2013-03-07 81 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

相关问题