java字典本地缓存_聊聊Java本地缓存

如今, 分布式缓存大行其道,比如Redis等, 但有些时候, 我们仅仅需要一个轻量级的本地缓存.

本地缓存的使用场景: 不需要被分布式共享、不需要持久化、数据规模小、更新频率低

本地缓存的使用优势:运行速度更快(因为无需进程或网络通信), 节省开发资源

本地缓存的设计重点:

1, 过期删除策略

2, 缓存淘汰策略

我们比较熟知的Java本地缓存有谷歌的Guava, 但Spring5已经弃用Guava而选择了Caffeine, 据说后者性能更佳, “缓存淘汰策略”设计的更加优秀.

下面说一下上面提到的2种策略

过期删除策略

对于设置了过期时间的缓存,删除策略一般分为: 定期删除、惰性删除.

定期删除:单独的线程对数据进行过期检查

惰性删除:当数据被查询时再判断是否过期

缓存淘汰策略

当缓存容量不足时, 需要开启淘汰机制, 缓存淘汰策略常见的有: FIFO、LRU、LFU

FIFO(First In First out): 先进先出

当资源不足时, 干掉那些先出生的老人, 简单粗暴, 但是可能造成经常使用的缓存被无辜淘汰.

LRU(Least recently used): 最近最少使用

LRU机制要求put缓存时,将数据放在链表的头部, get缓存时将数据移到链表的头部, 保证了最近使用的数据都在链表的头部区域, 最近最少使用的数据都在链表的尾部, 这样需要淘汰缓存时, 直接移除链表尾部的数据即可.

LFU(Least frequently used): 最少频率使用

LFU和LRU虽然都是基于“最少”使用,但“率”似乎更加准确, 就像现实中,我们经常用“增长率”来衡量增长指标一样.

上面3种策略, 最常使用的是LRU, 可以满足绝大多数场景, 实现起来也比较简单, Guava就采用了LRU策略, 但总有人精益求精, 提出一些新的策略, 比如Caffeine的W-TinyLFU.

如果一个独立的应用, 可预见的数据规模小,不需要考虑内存不足时“缓存淘汰”,只需要“缓存过期”机制, 则我们可以自定义一个简单的本地缓存.

import java.util.Date;

import java.util.concurrent.ConcurrentHashMap;

/**

* 简单本地缓存器,适用于小规模的静态数据缓存。

* 失效策略:"惰性删除",即每次查询时进行失效判断

* 淘汰策略: 无

* @Author:tt

* @Description:

* @CreateTime:2018/11/11

*/

public class SimpleLocalCache {

//ConcurrentHashMap并发读写

private static ConcurrentHashMap cacheArea = new ConcurrentHashMap<>();

//取缓存

public static Object get(String key) {

CacheData cacheData = cacheArea.get(key);

if (cacheData == null) {

return null;

}

if (isDead(cacheData)) {

//惰性删除

remove(key);

return null;

}

return cacheData.getValue();

}

//放缓存

public static boolean put(String key, Object value, long maxAge) {

CacheData data = new CacheData();

data.setCreateTime(new Date().getTime());

data.setMaxAge(maxAge);

data.setKey(key);

data.setValue(value);

cacheArea.put(key, data);

return false;

}

//是否过期

private static boolean isDead(CacheData data) {

if (data == null) {

return true;

}

if (data.getMaxAge() == 0) {

return false;

}

long createTime = data.getCreateTime();

long deadTime = createTime + data.getMaxAge();

long nowTime = new Date().getTime();

if (nowTime > deadTime) {

return true;

}

return false;

}

//移除

public static boolean remove(String key) {

cacheArea.remove(key);

return true;

}

//缓存数据封装

static class CacheData {

//创建时间:单位毫秒

private long createTime;

//缓存时常:单位毫秒, 0-标示永不失效

private long maxAge;

//数据key

private String key;

//数据value

private Object value;

public long getCreateTime() {

return createTime;

}

public void setCreateTime(long createTime) {

this.createTime = createTime;

}

public long getMaxAge() {

return maxAge;

}

public void setMaxAge(long maxAge) {

this.maxAge = maxAge;

}

public String getKey() {

return key;

}

public void setKey(String key) {

this.key = key;

}

public Object getValue() {

return value;

}

public void setValue(Object value) {

this.value = value;

}

}

//测试

public static void main(String[] args) throws InterruptedException {

SimpleLocalCache.put("key1", "v1", 1000);

SimpleLocalCache.put("key2", "v2", 5000);

SimpleLocalCache.put("key3", "v3", 0);

Thread.sleep(3000);

System.out.println(SimpleLocalCache.get("key1"));

System.out.println(SimpleLocalCache.get("key2"));

System.out.println(SimpleLocalCache.get("key3"));

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值