Java缓存Map设置过期时间实现解析
这篇文章主要介绍了Java缓存Map设置过期时间实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
前言
最近项目需求需要一个类似于redis可以设置过期时间的K,V存储方式。项目前期暂时不引进redis,暂时用java内存代替。
解决方案
1.ExpiringMap
功能简介:
1.可设置Map中的Entry在一段时间后自动过期。
2.可设置Map最大容纳值,当到达Maximumsize后,再次插入值会导致Map中的第一个值过期。
3.可添加监听事件,在监听到Entry过期时调度监听函数。
4.可以设置懒加载,在调用get()方法时创建对象。
github地址:https://github.com/jhalterman/expiringmap/
maven添加依赖即可使用
net.jodah expiringmap 0.5.8
publicstaticvoidmain(String[]args)throwsInterruptedException{ ExpiringMapmap=ExpiringMap.builder() .maxSize(100) .expiration(1,TimeUnit.SECONDS) .expirationPolicy(ExpirationPolicy.ACCESSED) .variableExpiration() .build(); map.put("test","test123"); Thread.sleep(500); Stringtest=map.get("test"); System.err.println(test); }
2.Guava-LoadingCache
Google开源出来的一个线程安全的本地缓存解决方案。
特点:提供缓存回收机制,监控缓存加载/命中情况,灵活强大的功能,简单易上手的api
但是该cache不会在特定时间准时回收键值,所以不适用于我当前的业务场景。
com.google.guava guava 27.1-jre
3.ExpiryMap
这是网上某位大佬自己封装的map,继承至HashMap,重写了所有对外的方法,对每个key值都设置了有效期。
我在其基础上增加了使用单例模式获取map。
importjava.util.*; /** *@Title:ExpiryMap可以设置过期时间的Map *@descriptionExpiryMap继承至HashMap重写了所有对外的方法,对每个key值都设置了有效期 *@Author:xx *@Version:1.0 */ publicclassExpiryMapextendsHashMap { privatestaticfinallongserialVersionUID=1L; /** *defaultexpirytime2s */ privatelongEXPIRY=1000*2; privateHashMap expiryMap=newHashMap<>(); /**缓存实例对象*/ privatevolatilestaticExpiryMap SameUrlMap; /** *采用单例模式获取实例 *@return */ publicstaticExpiryMapgetInstance(){ //第一次判空,提高效率 if(null==SameUrlMap){ //保证线程安全 synchronized(ExpiryMap.class){ //第二次判空,保证单例对象的唯一性,防止第一次有多个线程进入第一个if判断 if(null==SameUrlMap){ SameUrlMap=newExpiryMap<>(); } } } returnSameUrlMap; } publicExpiryMap(){ super(); } publicExpiryMap(longdefaultExpiryTime){ this(1<<4,defaultExpiryTime); } publicExpiryMap(intinitialCapacity,longdefaultExpiryTime){ super(initialCapacity); this.EXPIRY=defaultExpiryTime; } @Override publicVput(Kkey,Vvalue){ expiryMap.put(key,System.currentTimeMillis()+EXPIRY); returnsuper.put(key,value); } @Override publicbooleancontainsKey(Objectkey){ return!checkExpiry(key,true)&&super.containsKey(key); } /** *@paramkey *@paramvalue *@paramexpiryTime键值对有效期毫秒 *@return */ publicVput(Kkey,Vvalue,longexpiryTime){ expiryMap.put(key,System.currentTimeMillis()+expiryTime); returnsuper.put(key,value); } @Override publicintsize(){ returnentrySet().size(); } @Override publicbooleanisEmpty(){ returnentrySet().size()==0; } @Override publicbooleancontainsValue(Objectvalue){ if(value==null){ returnBoolean.FALSE; } Set >set=super.entrySet(); Iterator >iterator=set.iterator(); while(iterator.hasNext()){ java.util.Map.Entry entry=iterator.next(); if(value.equals(entry.getValue())){ if(checkExpiry(entry.getKey(),false)){ iterator.remove(); returnBoolean.FALSE; }else{ returnBoolean.TRUE; } } } returnBoolean.FALSE; } @Override publicCollection values(){ Collection values=super.values(); if(values==null||values.size()<1){ returnvalues; } Iterator iterator=values.iterator(); while(iterator.hasNext()){ Vnext=iterator.next(); if(!containsValue(next)){ iterator.remove(); } } returnvalues; } @Override publicVget(Objectkey){ if(key==null){ returnnull; } if(checkExpiry(key,true)){ returnnull; } returnsuper.get(key); } /** * *@Description:是否过期 *@paramkey *@returnnull:不存在或key为null-1:过期存在且没过期返回value因为过期的不是实时删除,所以稍微有点作用 */ publicObjectisInvalid(Objectkey){ if(key==null){ returnnull; } if(!expiryMap.containsKey(key)){ returnnull; } longexpiryTime=expiryMap.get(key); booleanflag=System.currentTimeMillis()>expiryTime; if(flag){ super.remove(key); expiryMap.remove(key); return-1; } returnsuper.get(key); } @Override publicvoidputAll(Mapm){ for(Map.Entrye:m.entrySet()){ expiryMap.put(e.getKey(),System.currentTimeMillis()+EXPIRY); } super.putAll(m); } @Override publicSet >entrySet(){ Set >set=super.entrySet(); Iterator >iterator=set.iterator(); while(iterator.hasNext()){ java.util.Map.Entry entry=iterator.next(); if(checkExpiry(entry.getKey(),false)){ iterator.remove(); } } returnset; } /** * *@Description:是否过期 *@paramexpiryTimetrue过期 *@paramisRemoveSupertruesuper删除 *@return */ privatebooleancheckExpiry(Objectkey,booleanisRemoveSuper){ if(!expiryMap.containsKey(key)){ returnBoolean.FALSE; } longexpiryTime=expiryMap.get(key); booleanflag=System.currentTimeMillis()>expiryTime; if(flag){ if(isRemoveSuper){ super.remove(key); } expiryMap.remove(key); } returnflag; } publicstaticvoidmain(String[]args)throwsInterruptedException{ ExpiryMap map=newExpiryMap<>(); map.put("test","xxx"); map.put("test2","ankang",5000); System.out.println("test=="+map.get("test")); Thread.sleep(3000); System.out.println("test=="+map.get("test")); System.out.println("test2=="+map.get("test2")); Thread.sleep(3000); System.out.println("test2=="+map.get("test2")); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。