Guava缓存-Cache
Guava缓存-Cache
Kevin-air 发表于2年前
Guava缓存-Cache
  • 发表于 2年前
  • 阅读 127
  • 收藏 0
  • 点赞 0
  • 评论 0

【腾讯云】买域名送云解析+SSL证书+建站!>>>   

摘要: Guava Cache是一个全内存的本地缓存实现,它提供了线程安全的实现机制。整体上来说Guava cache 是本地缓存的不二之选,简单易用,性能好。

Guava Cache有两种创建方式:

  1. cacheLoader
  2. callable callback

  通过这两种方法创建的cache,和通常用map来缓存的做法比,不同在于,这两种方法都实现了一种逻辑——从缓存中取key X的值,如果该值已经缓存过了,则返回缓存中的值,如果没有缓存过,可以通过某个方法来获取这个值。但不同的在于cacheloader的定义比较宽泛,是针对整个cache定义的,可以认为是统一的根据key值load value的方法。而callable的方式较为灵活,允许你在get的时候指定。

示例

import com.google.common.cache.*;
import org.junit.Test;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author Kevin
 * @description
 * @date 2016/8/5
 */
public class CacheTest {

    @Test
    public void cacheLoaderTest() throws Exception {
        CacheLoader<String, String> cacheLoader = new CacheLoaderImpl();

        LoadingCache<String, String> cacheBuilder = CacheBuilder.newBuilder().maximumSize(1000).removalListener(new RemovalListenerImpl()).
                expireAfterAccess(5L, TimeUnit.SECONDS).build(cacheLoader);

        // read from database
        System.out.println("Kevin value:" + cacheBuilder.get("Kevin"));
        System.out.println("Han value:" + cacheBuilder.getUnchecked("Han"));

        // read from cache
        System.out.println("Kevin value:" + cacheBuilder.get("Kevin"));
        System.out.println("Han value:" + cacheBuilder.getUnchecked("Han"));

        // wait cache expire
        Thread.sleep(10000);

        // cache miss get EXPIRED notification
        System.out.println("Kevin value:" + cacheBuilder.get("Kevin"));
        System.out.println("Han value:" + cacheBuilder.getUnchecked("Han"));

        cacheBuilder.put("name", "Kevin");
        System.out.println("name value:" + cacheBuilder.get("name"));

        // async replace the key value ,get REPLACED notification
        cacheBuilder.refresh("name");

        // invalidate a key get EXPLICIT notification
        cacheBuilder.invalidate("name");
        System.out.println("name value:" + cacheBuilder.get("name"));

        // reload from databse then return value
        System.out.println(cacheLoader.load("name"));
    }


    @Test
    public void callbackCacheTest() throws ExecutionException {
        Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(1000).build();
        String result = cache.get("Kevin", new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("call me when cache miss");
                String value = "hello " + "Kevin" + "!";
                return value;
            }
        });
        System.out.println("Kevin value:" + result);

        result = cache.get("Kevin", new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("call me when cache miss");
                String value = "hello " + "Kevin" + "!";
                return value;
            }
        });
        System.out.println("Kevin value:" + result);
    }
}

class CacheLoaderImpl extends CacheLoader<String, String> {

    @Override
    public String load(String key) throws Exception {
        System.out.println("call me when cache miss,read from database...");
        String value = "hello " + key + "!";
        return value;
    }
}

// 缓存事件监听器
class RemovalListenerImpl implements RemovalListener<String, String> {

    @Override
    public void onRemoval(RemovalNotification<String, String> notification) {
        System.out.println("cause : " + notification.getCause() + ",key : " + notification.getKey() + ",value : " + notification.getValue());
    }
}

cache的参数说明:

  回收的参数:
  1. 大小的设置:CacheBuilder.maximumSize(long)  CacheBuilder.weigher(Weigher)  CacheBuilder.maxumumWeigher(long)
  2. 时间:expireAfterAccess(long, TimeUnit) expireAfterWrite(long, TimeUnit)
  3. 引用:CacheBuilder.weakKeys() CacheBuilder.weakValues()  CacheBuilder.softValues()
  4. 明确的删除:invalidate(key)  invalidateAll(keys)  invalidateAll()
  5. 缓存监听器:CacheBuilder.removalListener(RemovalListener)
  

  refresh机制:
  1. LoadingCache.refresh(K)  异步刷新对应key的值。
  2. CacheLoader.reload(K, V) 重新加载key的值并返回新的value。
  3. CacheBuilder.refreshAfterWrite(long, TimeUnit) 自动刷新cache。

guava Cache数据移除:

  1. 基于容量大小的移除,定义的方式一般为 CacheBuilder.maximumSize(long)
  2. 基于时间的移除,guava提供了两个基于时间移除的方法
        expireAfterAccess(long, TimeUnit)  这个方法是根据某个键值对最后一次访问之后多少时间后移除
        expireAfterWrite(long, TimeUnit)  这个方法是根据某个键值对被创建或值被替换后多少时间移除
  3. 基于引用的移除,这种移除方式主要是基于java的垃圾回收机制,根据键或者值的引用关系决定移除

自主移除,主动移除有三种方法:
  1.单独移除用 Cache.invalidate(key)
  2.批量移除用 Cache.invalidateAll(keys)
  3.移除所有用 Cache.invalidateAll()

如果需要在移除数据的时候有所动作还可以定义Removal Listener,但是有点需要注意的是默认Removal Listener中的行为是和移除动作同步执行的,如果需要改成异步形式,可以考虑使用RemovalListeners.asynchronous(RemovalListener, Executor)

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 13
博文 73
码字总数 26587
×
Kevin-air
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: