zoukankan      html  css  js  c++  java
  • Guava Cache本地缓存

    Guava介绍

    Guava是一种基于开源的Java库,其中包含谷歌正在由他们很多项目使用的很多核心库。

    这个库是为了方便编码,并减少编码错误。

    这个库提供用于集合,缓存,支持原语,并发性,常见注解,字符串处理,I/O和验证的实用方法。

    Guava Cache适用场景

    1 消耗一些内存空间来提升速度;

    2 缓存中存放的数据总量不会超出内存容量。

    (Guava Cache是单个应用运行时的本地缓存,不把数据存放到文件或外部服务器(Memcached, Redis))

    Guava Cache介绍

    数据结构:ConcurrentHash (The returned cache is implemented as a hash table with similar performance characteristics to ConcurrentHashMap.)

    主要特性(详见下面的相关链接):

        1 自动加载

        2 回收策略:

            2.1 基于容量

            2.2 基于存活时间

            2.3 基于权重

            2.4 基于引用

        3 移除监听器

        4 缓存访问统计

    主要接口:CacheBuilder, LoadingCache, CacheStats

    使用示例:

    public class CacheProTest {
        LoadingCache<Long, Person> cache;
        private int cacheTimeoutSeconds = 10; // 10秒
    
        Integer counter = 1;
    
        @Before
        public void initialize() {
            System.out.println("初始化");
    
            cache = CacheBuilder.newBuilder()
                            /* 回收策略:基于容量(least-recently-used eviction when a maximum size is exceeded) */
                            .maximumSize(10) 
                            // .initialCapacity(initialCapacity)
                            
                            /* 回收策略:基于存活时间(time-based expiration of entries, measured since last access or last write) */
                            .expireAfterWrite(cacheTimeoutSeconds, TimeUnit.SECONDS)
                            // .expireAfterAccess(duration, unit)
                            // .refreshAfterWrite(duration, unit)
                            
                            /* 回收策略:基于权重 */
                            // .maximumWeight(maximumWeight)
                            // .weigher(weigher)
    
                            /* 回收策略:基于引用(keys automatically wrapped in weak references, values automatically wrapped in weak or soft references)*/
                            // .weakKeys()
                            // .weakValues()
                            // .softValues()
                            
                            // 设置并发数为5,即同一时间最多只能有5个线程往cache执行写入操作
                            // .concurrencyLevel(concurrencyLevel)
    
                            /* 缓存访问统计(accumulation of cache access statistics) */
                            .recordStats()
                            
                            /* 移除监听器(notification of evicted (or otherwise removed) entries) */
                            // .removalListener(listener)
    
                            .build(new CacheLoader<Long, Person>() {
    
                                /* 自动加载(automatic loading of entries into the cache) */
                                @Override
                                public Person load(Long id) throws Exception {
                                    System.out.println("获取值, id=" + id);
    
                                    // 调用接口获取值
                                    Person p = new Person();
                                    p.setId(id);
                                    p.setName("name" + counter.toString());
                                    counter++;
    
                                    return p;
                                }
                            });
        }
    
        @Test
        public void test1() {
            try {
                /* 获值 */
                // ConcurrentMap<Long, Person> asMap = cache.asMap();
    
                // cache.get(key); //
                // cache.getAll(keys);
    
                // cache.getIfPresent(key);
                // cache.getAllPresent(keys);
    
                // cache.size();
    
                /* 存值 */
                // cache.put(key, value);
                // cache.putAll(m); // Map<? extends K, ? extends V> m
    
                /* 移除/删除 */
                // cache.refresh(key);
                // cache.invalidate(key);
                // cache.invalidateAll();
                // cache.invalidateAll(keys);
                // cache.cleanUp();
    
                /* 缓存访问统计 */
                CacheStats stats = cache.stats();
                stats.averageLoadPenalty();
                stats.evictionCount();
                stats.hitCount();
                stats.hitRate();
                stats.loadCount();
                stats.loadExceptionCount();
                stats.loadExceptionRate();
                stats.loadSuccessCount();
                stats.missCount();
                stats.missRate();
                stats.requestCount();
                stats.totalLoadTime();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        @Test
        public void test2() {
            try {
                Long id = 1L;
                Person person1 = cache.get(id);
    
                Thread.sleep(3L * 1000L);
                Person person2 = cache.get(id);
    
                Thread.sleep(11L * 1000L);
                Person person3 = cache.get(id);
    
                System.out.println(person1);
                System.out.println(person2);
                System.out.println(person3);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    class Person implements Serializable {
        private static final long serialVersionUID = 1L;
    
        private Long id;
    
        private String name;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return JSON.toJSONString(this);
        }
    }
    

      

    Guava Cache使用时需要关注的点

    1 了解LoadingCache.refresh

    正如LoadingCache.refresh(K)所声明,刷新表示为键加载新值,这个过程可以是异步的。

    在刷新操作进行时,缓存仍然可以向其他线程返回旧值,而不像回收操作,读缓存的线程必须等待新值加载完成。

    如果刷新过程抛出异常,缓存将保留旧值,而异常会在记录到日志后被丢弃[swallowed]。

    重载CacheLoader.reload(K, V)可以扩展刷新时的行为,这个方法允许开发者在计算新值时使用旧的值。

    2 了解 清理时机

    使用CacheBuilder构建的缓存不会"自动"执行清理和回收工作,也不会在某个缓存项过期后马上清理,也没有诸如此类的清理机制。

    它会在写操作时顺带做少量的维护工作,或者偶尔在读操作时做——如果写操作实在太少的话。

    因此使用LoadingCache.size() 一定要关注这个点。

    相关链接

    github 地址

    易宝教程:Guava教程

    CSDN:GuavaCache简介

    并发编程网:[Google Guava] 3-缓存

  • 相关阅读:
    关于C#中Environment.OSVersion判断操作系统及Win10上的问题
    C#各种数组直接的数据复制/转换
    移位操作<<和>>,是逻辑数字上的移动(和大端小端无关)
    log4net学习笔记
    链接错误——无法解析的外部符号 ConvertStringToBST
    当Thread.Sleep的暂停时间参数设置过小时,精度很差的解决方法
    Python发送邮件
    Python使用HTMLTestRunner运行所有用例并产生报告
    pandas学习笔记
    Python requests模块做接口测试
  • 原文地址:https://www.cnblogs.com/ken-jl/p/8997853.html
Copyright © 2011-2022 走看看