Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why setting expireAfterAccess does not work?

Why does the timedCachetest fails on the last line? Why cache is not empty after 60 seconds?

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;
    }
}
like image 239
hash Avatar asked Oct 19 '25 12:10

hash


1 Answers

It's stated right there in the 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 caches do maintenance either when it's specifically requested, or when it can do so as part of a cache mutation, or occasionally on reads. It doesn't e.g. start a thread to do cache maintenance, because a) threads are relatively heavyweight, and b) some environments restrict the creation of threads.

like image 175
Louis Wasserman Avatar answered Oct 21 '25 00:10

Louis Wasserman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!