概述
Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。Hutool是由中国人开源,API的设计和中文注释都十分好用。
今天主要介绍下Hutool中的本地缓存API,它提供了各种各样的缓存策略供我们使用,十分简单方便。本地缓存在某些场景还是很好用的,相对于分布式缓存,基本上不用担心因为网络等原因导致的数据不一致,那直接看例子吧。
缓存创建API
CacheUtil
类是一个可以创建各种类型缓存的工厂类,默认提供了下面6种缓存的创建:
- FIFOCache: 先进先出缓存
- 元素不停的加入缓存直到缓存满为止,当缓存满时,清理过期缓存对象,清理后依旧满则删除先入的缓存(链表首部对象)
- 优点:简单快速
- 缺点:不灵活,不能保证最常用的对象总是被保留
- API:
static <K, V> FIFOCache<K, V> newFIFOCache(int capacity, long timeout)
- LFUCache: 最少使用率缓存
- 根据使用次数来判定对象是否被持续缓存,使用率是通过访问次数计算的。
- 清理后依旧满的情况下清除最少访问(访问计数最小)的对象并将其他对象的访问数减去这个最小访问数,以便新对象进入后可以公平计数。
- API:
static <K, V> LFUCache<K, V> newLFUCache(int capacity, long timeout)
- LRUCache: 最近最久未使用缓存
- 根据使用时间来判定对象是否被持续缓存 当对象被访问时放入缓存,当缓存满了,最久未被使用的对象将被移除。
- 此缓存基于LinkedHashMap,因此当被缓存的对象每被访问一次,这个对象的key就到链表头部。
- 这个算法简单并且非常快,他比FIFO有一个显著优势是经常使用的对象不太可能被移除缓存。 缺点是当缓存满时,不能被很快的访问。
- API:
static <K, V> LRUCache<K, V> newLRUCache(int capacity, long timeout)
- TimedCache: 定时缓存
- 此缓存没有容量限制,对象只有在过期后才会被移除
- API:
static <K, V> TimedCache<K, V> newTimedCache(long timeout)
- WeakCache: 弱引用缓存
- 对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。
- 丢弃某个键时,其条目从映射中有效地移除。
- API:
static <K, V> WeakCache<K, V> newWeakCache(long timeout)
- NoCache: 不缓存
- 不实现缓存,用于快速关闭缓存。
- API:
static <K, V> NoCache<K, V> newNoCache()
缓存操作API
上面的几个缓存实现了同一个缓存接口Cache
,该接口封装了缓存操作的基本API, 比如添加、修改缓存等,以下是比较重要的几个接口。
- void put(K key, V object)
将对象加入到缓存,使用默认失效时长
- void put(K key, V object, long timeout)
将对象加入到缓存,使用指定失效时长
- V get(K key)
从缓存中获得对象,当对象不在缓存中或已经过期返回null
- V get(K key, Func0 supplier)
从缓存中获得对象,当对象不在缓存中或已经过期返回Func0回调产生的对象
- remove(K key)
从缓存中移除对象
- Iterator<CacheObj<K, V>> cacheObjIterator()
返回包含键和值得迭代器,用来遍历缓存数据
- Cache<K, V> setListener(CacheListener<K, V> listener)
设置监听器,用于实现缓存操作时的回调监听,例如缓存对象的移除事件等
缓存使用例子
我们介绍了一些相关的方法,那么直接上例子。
@Test public void fifoCacheTest(){ Cache<String,String> fifoCache = CacheUtil.newFIFOCache(3, 5000); fifoCache.setListener((key, value)->{ // 监听删除 System.out.println("remove:" + key + "——" + value); }); fifoCache.put("key1", "value1", DateUnit.SECOND.getMillis() * 3); fifoCache.put("key2", "value2", DateUnit.SECOND.getMillis() * 3); fifoCache.put("key3", "value3", DateUnit.SECOND.getMillis() * 3); fifoCache.put("key4", "value4", DateUnit.SECOND.getMillis() * 3); //由于缓存容量只有3,当加入第四个元素的时候,根据FIFO规则,最先放入的对象将被移除 String value1 = fifoCache.get("key1"); Assert.assertNull(value1); String key = "key5"; // 如果key从缓存中后去不到,调用Func方法返回的结果,并且保存到缓存中 String key5Value = fifoCache.get(key, new Func0<String>() { @Override public String call() throws Exception { // 比如从数据库获取数据 return "from db data " + key; } }); System.out.println("first get key5 value: " + key5Value); // 再次从缓存中获取,就有了 System.out.println("second get key5 value: " + fifoCache.get(key)); }
运行结果:
总结
本文总结了hutool工具类中缓存的api和使用,希望对大家有帮助。