本地缓存google Guava

时间:2022-01-10 20:45:25
1.引入依赖

GuavaCache是google开源Java类库Guava的其中一个模块,在maven工程下使用可在pom文件加入如下依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>23.0</version>
</dependency>
2.适用情况
  • 你愿意消耗一些内存空间来提升速度。
  • 你预料到某些键会被查询一次以上。
  • 缓存中存放的数据总量不会超出内存容量。(Guava Cache是单个应用运行时的本地缓存。它不把数据存放到文件或外部服务器。)
3.范例
//LoadingCache在缓存项不存在时可以自动加载缓存
    LoadingCache<String,Object> cache = CacheBuilder.newBuilder()
            //设置并发级别为8,并发级别是指可以同时写缓存的线程数
            .concurrencyLevel(8)
            //设置写缓存后8秒钟过期
            .expireAfterWrite(8, TimeUnit.SECONDS)
            //设置缓存容器的初始容量为10
            .initialCapacity(10)
            //设置缓存最大容量为100,超过100之后就会按照LRU最近虽少使用算法来移除缓存项
            .maximumSize(100)
            //设置缓存的移除通知
            .removalListener(new RemovalListener<String, Object>() {
                @Override
                public void onRemoval(
                        RemovalNotification<String, Object> notification) {
                    System.out.println(notification.getKey() + " was removed, cause is " + notification.getCause());
                }
            })
            //设置要统计缓存的命中率
            .recordStats()
            .build(new CacheLoader<String, Object>(){
                @Override
                public Object load(String key) throws Exception {
                    return null;
                }
            });
4.缓存回收
  • 基于容量的回收
//规定缓存项的最大数目
CacheBuilder.maximumSize(long)
//指定最大总重(权重)
CacheBuilder.maximumWeight(long)
  • 定时回收
//缓存项在给定时间内没有被读/写访问,则回收
expireAfterAccess(long, TimeUnit)
//缓存项在给定时间内没有被写访问(创建或覆盖),则回收
expireAfterWrite(long, TimeUnit)
  • 基于引用的回收
//使用弱引用存储键。当键没有其它(强或软)引用时,缓存项可以被垃圾回收。使用弱引用键的缓存用==比较。
CacheBuilder.weakKeys()
CacheBuilder.weakValues()
//使用软引用存储值。软引用只有在响应内存需要时,才按照全局最近最少使用的顺序回收。使用软引用值的缓存同样用==比较。
CacheBuilder.softValues():
  • 显示清除
//个别清除
Cache.invalidate(key)
//批量清除
Cache.invalidateAll(keys)
//清除所有缓存项
Cache.invalidateAll()
  • 移除监听器
CacheBuilder.removalListener(RemovalListener)//你可以声明一个监听器,以便缓存项被移除时做一些额外操作
  • 清理发生时机
    使用CacheBuilder构建的缓存不会”自动”执行清理和回收工作,也不会在某个缓存项过期后马上清理。相反,它会在写操作时顺带做少量的维护工作,或者偶尔在读操作时做——如果写操作实在太少的话。
5.缓存类的实现
package baseUtil.common.cache;

import java.util.concurrent.TimeUnit;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.Weigher;


public abstract class GuavaCache<K,V>{

        private LoadingCache<K,V> cache;

        public GuavaCache()
        {
            cache = CacheBuilder.newBuilder()
                    .maximumSize(1000)
                    .build(new CacheLoader<K, V>() {
                        @Override
                        public V load(K k) throws Exception
                        {
                            return loadData(k);
                        }
                    });
        }

        /** * 超时缓存:数据写入缓存超过一定时间自动刷新 * @param duration * @param timeUtil */
        public GuavaCache(long duration, TimeUnit timeUtil)
        {
            cache = CacheBuilder.newBuilder()
                    .expireAfterWrite(duration, timeUtil)
                    .build(new CacheLoader<K, V>() {
                        @Override
                        public V load(K k) throws Exception
                        {
                            return loadData(k);
                        }
                    });
        }

        /** * 限容缓存:缓存数据个数不能超过maxSize * @param maxSize */
        public GuavaCache(long maxSize)
        {
            cache = CacheBuilder.newBuilder()
                    .maximumSize(maxSize)
                    .build(new CacheLoader<K, V>() {
                        @Override
                        public V load(K k) throws Exception
                        {
                            return loadData(k);
                        }
                    });
        }

        /** * 权重缓存:缓存数据权重和不能超过maxWeight * @param maxWeight * @param weigher:权重函数类,需要实现计算元素权重的函数 */
        public GuavaCache(long maxWeight, Weigher<K, V> weigher)
        {
            cache = CacheBuilder.newBuilder()
                    .maximumWeight(maxWeight)
                    .weigher(weigher)
                    .build(new CacheLoader<K, V>() {
                        @Override
                        public V load(K k) throws Exception
                        {
                            return loadData(k);
                        }
                    });
        }


        /** * 缓存数据加载方法 * @param key */
        protected abstract V loadData(K key);

        /** * 从缓存获取数据 * @param key * @return value */
        public V getData(K key)
        {
            return cache.getUnchecked(key);
        }

        /** * 主动设置缓存数据 * @param key * @param value */
        public void saveData(K key, V value)
        {
            cache.put(key, value);
        }

        /** * 清除单个缓存数据 * @param key */
        public void deleteData(K key){
            cache.invalidate(key);
        }

        /** * 清除所有缓存数据 */
        public void clear() {
            cache.invalidateAll();
        }

        /** * 刷新缓存数据,数据会重新调用load方法获取 * @param key */
        public void refresh(K key)
        {
            cache.refresh(key);
        }



}