基于ConcurrentHashMap的本地缓存


在系统中,有些数据,数据量小,但是访问十分频繁(例如国家标准行政区域数据),针对这种场景,需要将数据搞到应用的本地缓存中,以提升系统的访问效率,减少无谓的数据库访问(数据库访问占用数据库连接,同时网络消耗比较大),但是有一点需要注意,就是缓存的占用空间以及缓存的失效策略

代码实现

package com.mine.localcache;

import java.util.Date;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap; /**
* ******************************
* createTime: 2019/7/15 9:56
* description: 基于ConcurrentHashMap的本地缓存解决方案
* version: V1.0
* ******************************
*/
public class LocalCache { /**
* 默认有效时长,单位:秒
*/
private static final int DEFUALT_TIMEOUT = 3600 * 1000; private static final long SECOND_TIME = 1000; private static final Map<String, Object> map; private static Timer timer; /**
* 初始化
*/
static {
timer = new Timer();
map = new ConcurrentHashMap<>();
} /**
* 私有构造函数,工具类不允许实例化
*/
private LocalCache() {} /**
* 清除缓存任务类
*/
static class CleanWorkerTask extends TimerTask { private String key; public CleanWorkerTask(String key) {
this.key = key;
} public void run() {
LocalCache.remove(key);
}
} /**
* 增加缓存
*
* @param key
* @param value
*/
public static void put(String key, Object value) {
map.put(key, value);
timer.schedule(new CleanWorkerTask(key), DEFUALT_TIMEOUT);
} /**
* 增加缓存
*
* @param key
* @param value
* @param timeout 有效时长
*/
public static void put(String key, Object value, int timeout) {
map.put(key, value);
timer.schedule(new CleanWorkerTask(key), timeout * SECOND_TIME);
} /**
* 增加缓存
*
* @param key
* @param value
* @param expireTime 过期时间
*/
public static void put(String key, Object value, Date expireTime) {
map.put(key, value);
timer.schedule(new CleanWorkerTask(key), expireTime);
} /**
* 批量增加缓存
*
* @param m
*/
public static void putAll(Map<String, Object> m) {
map.putAll(m); for (String key : m.keySet()) {
timer.schedule(new CleanWorkerTask(key), DEFUALT_TIMEOUT);
}
} /**
* 批量增加缓存
*
* @param m
*/
public static void putAll(Map<String, Object> m, int timeout) {
map.putAll(m); for (String key : m.keySet()) {
timer.schedule(new CleanWorkerTask(key), timeout * SECOND_TIME);
}
} /**
* 批量增加缓存
*
* @param m
*/
public static void putAll(Map<String, Object> m, Date expireTime) {
map.putAll(m); for (String key : m.keySet()) {
timer.schedule(new CleanWorkerTask(key), expireTime);
}
} /**
* 获取缓存
*
* @param key
* @return
*/
public static Object get(String key) {
return map.get(key);
} /**
* 查询缓存是否包含key
*
* @param key
* @return
*/
public static boolean containsKey(String key) {
return map.containsKey(key);
} /**
* 删除缓存
*
* @param key
*/
public static void remove(String key) {
map.remove(key);
} /**
* 删除缓存
*
* @param o
*/
public static void remove(Object o) {
map.remove(o);
} /**
* 返回缓存大小
*
* @return
*/
public static int size() {
return map.size();
} /**
* 清除所有缓存
*
* @return
*/
public static void clear() {
if (size() > 0) {
map.clear();
} // 取消延时任务,重新创建Timer
timer.cancel();
timer = new Timer();
}
}

测试Demo

public class TestDemo {

    public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 20000; i++) {
LocalCache.put(i + "", "test for " + i , 20);
} System.out.println("ok"); Thread.sleep(10 * 1000); for (int i = 0; i < 20000; i++) {
System.out.println(LocalCache.get(i + ""));
} Thread.sleep(15 * 1000); for (int i = 0; i < 20000; i++) {
System.out.println(LocalCache.get(i + ""));
}
}
}

总结分析

该缓存是基于ConcurrentHashMap配合Timer实现的本地缓存策略,但是它有其瓶颈,比如:
LRU:Least Recently Used,最近最少使用 算法实现等
都均未实现,不过可以用作学习和参考使用 生产级别推荐使用:Guava cache构建本地缓存

最新文章

  1. 史航416第十次作业&amp;总结
  2. [OC笔记]我的第一个OC程序
  3. Android消息队列和Looper
  4. 连载《一个程序猿的生命周期》-6、自学C++,二级考过后,为工作的机会打下了基础
  5. 最短路算法 (bellman-Ford算法)
  6. 【前端学习】sublime开启vim模式
  7. winform打包关键部分
  8. 设置ASP.NET MVC站点默认页为html页
  9. linux命令存放 bash: xxx command not found
  10. elasticsearch 集群配置
  11. tespeed-测试网速的Python工具
  12. Mac 系统显示和隐藏文件的方法
  13. [置顶] 小伙伴们来自己实现LinkedList
  14. C#在outlook里创建一封邮件到草稿箱
  15. 大数据时代之hadoop(四):hadoop 分布式文件系统(HDFS)
  16. 【Swift】swift定义全局变量
  17. ROS机器人程序设计(原书第2版)补充资料 (陆) 第六章 点云 PCL
  18. Win10激活工具
  19. db mysql / mysql cluster 5.7.19 / my.cnf / max_binlog_cache_size / binlog
  20. 关于jquery中on绑定click事件在苹果手机失效的问题

热门文章

  1. Arduino控制超声波检测与0.96OLED及串口显示
  2. 4a-c++ primer宽字符wchar_t显示设置与输出代码示例
  3. PyCharm远程连接服务器简明教程
  4. C/C++以及Linux文件操作备忘录
  5. 阿里druid数据源属性配置表
  6. centos 6.5 dhcp桥接方式上网络设置
  7. Python3-collections模块-容器数据类型
  8. MySQL8.0窗口函数实践及小结
  9. vs2010调试运行时弹出对话框:系统找不到指定文件
  10. Glusterfs的安装、创建卷、配置和优化卷、挂载使用