Google Guava LoadingCache 入门使用指南

请看文档注释。

package com.abc.test

import com.google.common.cache.CacheBuilder
import com.google.common.cache.CacheLoader
import com.google.common.cache.LoadingCache
import com.google.common.cache.RemovalListener
import org.junit.Assert
import org.junit.Test
import java.time.Duration

/**
 *
 */
class GuavaLoadingCacheTest {

    /**
     * LoadingCache的数据来源是CacheLoader。
     * 通过查看CacheLoader的打印日志可以看出:
     * 当第一次取“1”和“2”的时候,会从CacheLoader获取,
     * 下一次取“1”和“2”的时候,直接从Cache获取,
     * CacheLoader不再打印日志.
     */
    @Test
    fun testCache() {
        val loadingCache: LoadingCache<String, String> =
            CacheBuilder.newBuilder().maximumSize(2)
                .build(object : CacheLoader<String, String>() {
                    @Throws(Exception::class)
                    override fun load(s: String): String {
                        println("Loading $s")
                        return s
                    }
                })
        loadingCache.get("0");
        loadingCache.get("1");
        loadingCache.get("0");
        loadingCache.get("1");
    }

    /**
     * 测试CacheBuilder的expireAfterAccess方法,
     * 此处CacheBuilder的expireAfterAccess设置为1秒,
     * 也即首次获取某个元素1秒之后,这个元素会失效,会从cache中移除,重新从CacheLoader中取
     * 通过查看CacheLoader的打印日志可以看出在主线程sleep2秒之后去取"0"和“1”,CacheLoader打印出了日志,
     * 说明之前的cache已经失效.
     */
    @Test
    fun testExpireAfterAccess() {
        val loadingCache: LoadingCache<String, String> =
            CacheBuilder.newBuilder().expireAfterAccess(Duration.ofSeconds(1))
                .build(object : CacheLoader<String, String>() {
                    @Throws(Exception::class)
                    override fun load(s: String) = s.also { println("Loading $it") }
                })
        loadingCache.get("0");
        loadingCache.get("1");
        Thread.sleep(Duration.ofSeconds(2).toMillis());
        loadingCache.get("0");
        loadingCache.get("1");
    }

    /**
     * 测试CacheBuilder的maximumSize,
     * 此处CacheBuilder的maximumSize设置为2个,
     * 先获取"0"和“1”,目前cache已满(["0","1"]),继续获取“2”,通过RemovalListener得知会清除第一个元素“0”,现在的cache也是满的
     * 元素是["1",“2”],可以继续获取元素“0”,通过RemovalListener得知会清除第一个元素“1”
     *
     */
    @Test
    fun testMaximumSize() {
        val l: RemovalListener<String, String> = RemovalListener<String, String> {
            println("Remove: ${it.key}")
        }
        val loadingCache: LoadingCache<String, String> =
            CacheBuilder.newBuilder().maximumSize(2).removalListener(l)
                .build(object : CacheLoader<String, String>() {
                    @Throws(Exception::class)
                    override fun load(s: String) = (s + s).also { println("Loading $s") }
                })
        loadingCache.get("0");
        loadingCache.get("1");
        loadingCache.get("2");
        loadingCache.get("0");
    }

    /**
     * 测试CacheBuilder的expireAfterWrite,
     * put进去cache的元素会在指定的时间内失效,此处为1秒。
     *  loadingCache.put("10", "10"),
     *  然后主线程等待2秒之后再去执行  loadingCache.get("10")
     *  会发现是从CacheLoader 获取,证明cache中没有此key的元素.
     */
    @Test
    fun testExpireAfterWrite() {
        val loadingCache: LoadingCache<String, String> =
            CacheBuilder.newBuilder().expireAfterWrite(Duration.ofSeconds(1))
                .build(object : CacheLoader<String, String>() {
                    @Throws(Exception::class)
                    override fun load(s: String) = s.also { println("Loading $s") }
                })
        loadingCache.put("10", "10")
        Thread.sleep(Duration.ofSeconds(2).toMillis())
        loadingCache.get("10")
    }

}


你可能感兴趣的:(guava,缓存)