最近在做zuul的限流功能!在filter中我用ConCurrentHashMap计数,然而map中的key没有失效删除的地方。

于是就搜了一下,结果搜到的结果不是很满意,很多搜到的实现都是让key失效了,但是还是保存在map中!我真正想要的是能够让key定时失效,失效的key被gc!

所以按如下规则自己写了一个map:

1、该map的实现基于ConcurrentMap,在并发情况下保证了线程安全;

2、该map没存保存key、value的时候,都要同同时保存key的有效时间;

3、该map自带一个定时任务,每次定时任务触发都会遍历该map清除失效的key-value,并释放缓存。

不多说了,代码如下:


import java.util.*;
import java.util.concurrent.ConcurrentHashMap;/*** @Description: 带有效期的Map。* 每个key存入该map时,都需要设置key的有效期!当超期后,该key失效!* 此外,该map加入了一个定时器,每间隔一段时间,就自动扫描该map一次,清除失效的key* @author:  yu.jinlong* @Date: 2019-11-22 16:42:50* @param <K>* @param <V>*/
public class ExpiryMap<K, V> implements Map<K, V> {private boolean isRefresh = false;private ConcurrentHashMap workMap = new ConcurrentHashMap();private ConcurrentHashMap<Object, Long> expiryMap = new ConcurrentHashMap<>();public ExpiryMap() {super();scheduleRemoveInValidKeys();}public ExpiryMap(boolean isRefresh) {this.isRefresh = isRefresh;scheduleRemoveInValidKeys();}/*** 定时清除失效key*/private void scheduleRemoveInValidKeys() {int interval = 60;//频率,常规情况下执行多少次,扫描一次失效keyint threshold = 10000;//map的容量阈值,达到该值后,将较频繁的执行key扫描工作!new Timer().schedule(new TimerTask() {int i = 0;@Overridepublic void run() {System.out.println("111111");boolean isRun = ++i % interval == 0 || expiryMap.keySet().size() > threshold;if (isRun) {removeInValidKeys();}}}, 1000, 1000);//每隔1秒启动一次扫码}private void removeInValidKeys(){expiryMap.keySet().forEach(key->{if(expiryMap.get(key) < System.currentTimeMillis()){expiryMap.remove(key);workMap.remove(key);}});System.gc();}/**** @param key key 的有效期!单位为:毫秒* @param expiry* @return*/public Long addAndGet(K key,long expiry){Long value=0l;if(containsKey(key)){value = (Long)workMap.get(key);}workMap.put(key,++value);if(!containsKey(key)||isRefresh){expiryMap.put(key,System.currentTimeMillis() + expiry);}return value;}/*** put方法,需要设置key 的有效期!单位为:毫秒* @param key* @param value* @param expiry key的有效期,单位:毫秒* @return*/public V put(K key, V value, long expiry) {if (!containsKey(key) || isRefresh) {//更新value,只有需要刷新时间时才需要操作expiryMapexpiryMap.put(key, System.currentTimeMillis() + expiry);}workMap.put(key, value);return value;}@Overridepublic int size() {return keySet().size();}@Overridepublic boolean isEmpty() {return size() == 0;}@Overridepublic boolean containsKey(Object key) {if (key!=null &&expiryMap.containsKey(key)) {boolean flag = expiryMap.get(key) > System.currentTimeMillis();if(!flag){//key已经失效,则删除之expiryMap.remove(key);workMap.remove(key);}return flag;}return false;}@Overridepublic boolean containsValue(Object value) {Collection values = workMap.values();if(values!=null){return values.contains(value);}return false;}@Overridepublic V get(Object key) {if (containsKey(key)) {return (V) workMap.get(key);}return null;}@Deprecated@Overridepublic V put(K key, V value) {throw new RuntimeException("此方法已废弃!请加上key失效时间");}@Overridepublic V remove(Object key) {boolean flag =  containsKey(key);expiryMap.remove(key);V v=(V) workMap.remove(key);return flag?v:null;}@Deprecated@Overridepublic void putAll(Map<? extends K, ? extends V> m) {throw new RuntimeException("此方法已废弃!");}@Overridepublic void clear() {expiryMap.clear();workMap.clear();}@Overridepublic Set<K> keySet() {removeInValidKeys();return workMap.keySet();}@Overridepublic Collection<V> values() {removeInValidKeys();return workMap.values();}@Overridepublic Set<Entry<K, V>> entrySet() {removeInValidKeys();return workMap.entrySet();}}

Java带有效期的Map相关推荐

  1. java集合课程,I学霸官方免费课程三十三:Java集合框架之Map集合

    I学霸官方免费教程三十三:Java集合框架之Map集合 Map接口 Map集合采用键值对(key-value)的方式存储数据,其中键不可以重复.值可以重复. 常用类有HashMap.TreeMap和P ...

  2. java集合框架07——Map架构与源代码分析

    前几节我们对Collection以及Collection中的List部分进行了分析,Collection中还有个Set,因为Set是基于Map实现的,所以这里我们先分析Map,后面章节再继续学习Set ...

  3. java中map怎么遍历,Java中怎么遍历Map的所有的元素

    Java中怎样遍历Map的所有的元素 JDK1.4中 view plaincopy to clipboardprint? Map map = new HashMap(); Iterator it = ...

  4. Java基础知识之Map:compute, computeIfAbsent, computeIfPresent

    Java基础知识之Map:compute, computeIfAbsent, computeIfPresent 功能 default V compute(K key, BiFunction<? ...

  5. java list for循环遍历_详解Java中list,set,map的遍历与增强for循环

    详解Java中list,set,map的遍历与增强for循环 Java集合类可分为三大块,分别是从Collection接口延伸出的List.Set和以键值对形式作存储的Map类型集合. 关于增强for ...

  6. Java之五种遍历Map集合的方式

    摘要:在java中所有的map都实现了Map接口,因此所有的Map都可以用以下的方式去遍历. 在java中所有的map都实现了Map接口,因此所有的Map都可以用以下的方式去遍历.这篇文章主要给大家介 ...

  7. java集合for循环_详解Java中list,set,map的遍历与增强for循环

    详解Java中list,set,map的遍历与增强for循环 Java集合类可分为三大块,分别是从Collection接口延伸出的List.Set和以键值对形式作存储的Map类型集合. 关于增强for ...

  8. java 怎么获取键的值_在 Java 中如何获取 Map 的所有键和值

    在 Java 中可以通过 map.entrySet() 方法获取 Map 的所有键和值. Map map = new HashMap<>(); // Get keys and values ...

  9. java 集合之Interface Map<K,V> HashMap实现类

    java 集合之Interface Map<K,V> 类型参数:K- 此映射所维护的键的类型:V- 映射值的类型 将键映射到值的对象. 一个映射不能包含重复的键: 每个键最多可以映射到一个 ...

  10. JAVA带财务进销存ERP管理系统源码,免费分享源码

    JAVA带财务进销存ERP管理系统源码 开发语言 : JAVA 数据库 : MySQL 开发工具 : Eclipse 源码类型:全开源免费分享,需要源码学习可以私信我. 系统概述: 系统主要模块有零售 ...

最新文章

  1. 用GPUDirect RDMA技术做的代码测试
  2. iOS Block全面分析
  3. 一致性协议浅析:从逻辑时钟到Raft
  4. matlab桥梁受力计算公式,matlab桥梁计算
  5. orchard mysql_Orchard Core创建CMS/Blog站点
  6. Landsat 8 数据获取
  7. js实现网页中简体与繁体互转
  8. 关于AE(AfterEffect)安装QuickTime后无法渲染H.264,出现报错问题的解决!!错误代码(-1610153459)
  9. python识图 web_python+flask搭建CNN在线识别手写中文网站
  10. 如何做好风险控制,规避项目中的风险
  11. 网站攻击怎么来的,如何攻击?
  12. 登录注册小程序(JAVA基础案例教程第二章-课后作业)
  13. ♠Linux命令随笔
  14. 图解域名解析成IP的全过程(你浏览器摁下一个网址后发生了啥?)
  15. 【系统设计】系统设计基础:速率限制器
  16. 三个等号和二个等号的区别是
  17. 混杂模式和非混杂模式
  18. iOS中 HeathKit框架学习 步数统计等 韩俊强的博客
  19. 四位行波进位加法器_【HDL系列】半加器、全加器和行波进位加法器原理与设计...
  20. 高效能人士的执行四原则(三)——原则2:关注引领性指标

热门文章

  1. 测试方案包括哪些内容
  2. Java代码利用aspose-words将word文档转换成pdf和图片格式(PNG,JPG,JPEG破解 无水印)
  3. python如何计算等额本息还款_银行等额本息还款算法
  4. androidbenchmark和iphonebenchmark这两页面中设备信息爬虫
  5. 磁盘管理高级进阶-LVM逻辑卷管理
  6. QtSQL的使用心得
  7. 遇到问题---linux--shell--Argument list too long
  8. c语言1%3等于多少,%取余语句1%3等于多少的作用
  9. 谈谈对计算机网络的了解,对计算机网络的认识和了解
  10. php相册照片批量修改,php如何实现批量修改文件名称