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

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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-缓存

 

posted @   ken-jl  阅读(2309)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示