龙空技术网

java 本地缓存 Guava Cache 带你入门!

仗剑走天涯 69

前言:

而今朋友们对“网盘java缓存数据”都比较关注,同学们都想要了解一些“网盘java缓存数据”的相关文章。那么小编也在网络上网罗了一些有关“网盘java缓存数据””的相关内容,希望你们能喜欢,大家快快来了解一下吧!

缓存分为本地缓存和远端缓存。

常见的远端缓存有Redis,MongoDB;本地缓存一般使用map的方式保存在本地内存中。

一般我们在业务中操作缓存,都会操作缓存和数据源两部分。

如:

put数据时,先插入DB,再删除原来的缓存;

get数据时,先查缓存,命中则返回,没有命中时,需要查询DB,再把查询结果放入缓存中 。

如果访问量大,我们还得兼顾本地缓存的线程安全问题。

必要的时候也要考虑缓存的回收策略。

Guava Cache

回收、驱逐、监听、刷新等功能。

缓存回收的时机

关于这点,只需要知道 Guava cache 缓存不会”自动”执行清理和回收工作,也不会在某个缓存项过期后马上清理,也没有诸如此类的清理机制。相反,它会在写操作时顺带做少量的维护工作,或者偶尔在读操作时做——如果写操作实在太少的话。

这样做的原因在于:如果要自动地持续清理缓存,就必须有一个线程,这个线程会和用户操作竞争共享锁。此外,某些环境下线程创建可能受限制,这样 CacheBuilder 就不可用了。

代码展示

@Componentpublic class CacheLocalConfigService {    private static Logger logger = LoggerFactory.getLogger(CacheLocalConfigService.class);    /** 缓存值的最大数 */    private int maximumSize = 1000;    private Cache<String,Object> cache = null;    public CacheLocalConfigService()    {        super();    }    public int getMaximumSize()    {        return maximumSize;    }    public void setMaximumSize(int maximumSize)    {        this.maximumSize = maximumSize;    }    /**     * 初始化。     */    @PostConstruct    public void init() {        cache = CacheBuilder.newBuilder()                //基于容量回收                //基于容量的清除:通过 CacheBuilder.maximumSize() 方法设置 Cache 的最大容量数,当缓存数量达到或接近该最大值时,将清除最近最少使用的缓存;                .maximumSize(this.maximumSize)                //并发级别 设置并发级别,并发级别是指可以同时写缓存的线程数                .concurrencyLevel(2)                //设置多久没被访问(读/写)的过期时间 -- expireAfterAccess指定对象多久没有被访问后过期。                .expireAfterAccess(60*10, TimeUnit.SECONDS)                //设置过期时间(写入3秒内过期)在一定时间内没有创建/覆盖时,会移除key,下次从loading中取                .expireAfterWrite(60*10, TimeUnit.SECONDS)                //.removalListener(async)                //设置缓存的移除通知                .removalListener(new RemovalListener<String, Object>() {                    @Override                    public void onRemoval(RemovalNotification<String, Object> notification) {                        logger.error("*********CacheLocalConfigService removalListener****"+notification.getKey() + " was removed, cause is " + notification.getCause());                    }                })                .recordStats()                .build();    }    /**     *     * 获取一个缓存,如果该缓存不存在则返回一个null值     * 获取{@linkplain Object}。     * @return 返回{@code null}表示没有缓存     */    public  Object getIfPresent(String key)    {        return this.cache.getIfPresent(key);    }    /**     * 添加至缓存。     * @param key     * @param o     */    public  void put(String key,Object o)    {        this.cache.put(key, o);    }    /**     * 清除指定名称缓存。     * @param key     */    public  void invalidate(String key)    {        this.cache.invalidate(key);    }    public String stats(){/*        hitRate():缓存命中率;        averageLoadPenalty():加载新值的平均时间,单位为纳秒;        evictionCount():缓存项被回收的总数,不包括显式清除。*/        return this.cache.stats().toString();    }}

标签: #网盘java缓存数据