java - 为什么设置 expireAfterAccess 不起作用?

标签 java caching testing guava

为什么 timedCachetest 在最后一行失败?为什么缓存在 60 秒后不为空?

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;
    }
}

最佳答案

它在 CacheBuilder Javadoc 中说明:

If expireAfterWrite or expireAfterAccess is requested entries may be evicted on each cache modification, on occasional cache accesses, or on calls to Cache.cleanUp(). Expired entries may be counted in Cache.size(), but will never be visible to read or write operations.

CacheBuilder 缓存会在特定请求时进行维护,或者当它可以作为缓存突变的一部分进行维护时,或者偶尔在读取时进行维护。它不是启动一个线程做缓存维护,因为a)线程比较重量级,b)有些环境限制线程的创建。

关于java - 为什么设置 expireAfterAccess 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15280974/

相关文章:

testing - 发现测试用例的方法有哪些

java - 由于 FacesValidator,ManageBean 方法不再有效?

java - 使用 JdbcDatasource 的迎风报告问题

c# - 使用缓存依赖项对 MVC 操作方法进行单元测试?

iphone - 使用 iOS 7 beta 对 iOS 应用程序进行 Beta 测试

unit-testing - 测试结果输出目录路径的 MSBuild/TFS Build 属性

java - 如何在绘画事件之间插入碰撞

java - Spring Integration Design - 处理文件中的行

caching - Azure 缓存不起作用(错误代码<ERRCA0017> :SubStatus<ES0006>). SDK 2.2

Asp.Net - ClientCache - 是否会因文件类型而异?