使用WeakHashMap创建具有过期时间的本地缓存
java中为了让程序员能参与到垃圾回收机制中(不是说java的GC是全自动的吗?这要看从哪个方面讲了,其实如果开发人员能熟练掌握java的gc原理,对提升系统的稳定性有极大帮助),设计了4种引用级别:分别是强引用(new 出来的)、软引用、弱引用和虚引用。
本文不打算介绍这几种引用的用法。还不了解它们的读者可以自行百度(国内的几个搜索引擎,还是百度 最适合程序员)。
不过如果能使用谷歌的还是要使用谷歌,因为各个级别都有大坑,使用不当可能完全发挥不了期望的效果。但是国内很少有文章讲其中的注意事项,可能是使用的场景太少了。而国外(比如dzone)的博客就不少。
弱引用的对象在每次垃圾回收的时候都会被处理掉。WeakHashMap就是利用了这个特性来实现的本地缓存。
WeakHashMap的具体用法也请百度。这里假设你已经在用WeakHashMap了
WeakHashMap实现的缓存虽然好用,但是不具备定时过期的特性。如果没有等到垃圾回收(或者我不去看监控根本不知道是否进行过垃圾回收),但是想更新缓存之值,就无能为力了!
所以这里我们个WeakHashMap增加一个过期时间。
有两种方式实现:
- 通过继承WeakHashMap实现
- 将WeakHashMap作为一个属性来实现
我们这里使用第一种,思路是把本来要放进WeakHashMap的东西附加一个当前时间。所以在写出继承WeakHashMap 的类之前先写一个附加时间点的封装类:
public class TimedLocalCachedDataDTO<V> { private final LocalDateTime time; private final V data; public TimedLocalCachedDataDTO(V data) { this.time = LocalDateTime.now(); this.data = data; } // getters }
这样,我们的WeakHashMap要放的对象都是TimedLocalCachedDataDTO
的实例:
public class TimedLocalCache<K, V> extends WeakHashMap<K, TimedLocalCachedDataDTO<V>> {
这个类里,我们给它指定一个过期时间:
public class TimedLocalCache<K, V> extends WeakHashMap<K, TimedLocalCachedDataDTO<V>> { private final long timeout; public TimedLocalCacheDTO(long timeout) { this.timeout = timeout; } /** * 默认5分钟过期 */ public TimedLocalCacheDTO() { timeout = TimeUnit.MINUTES.toSeconds(5); } public long getTimeout() { return timeout; }
然后在获取值的时候,如果根据key获取到值了,并不直接返回;而是先拿到放入的时间点加上过期时间与当前时间比较。下面分别是写入和读取的方法:
public TimedLocalCachedDataDTO<V> putCache(K key, V value) { TimedLocalCachedDataDTO<V> dataDTO = new TimedLocalCachedDataDTO<>(value); return super.put(key, dataDTO); }
public V getCache(K key) { TimedLocalCachedDataDTO<V> dataDTO = super.get(key); if (dataDTO == null) { return null; } LocalDateTime now = LocalDateTime.now(); LocalDateTime time = dataDTO.getTime(); long seconds = Duration.between(time, now).getSeconds(); if (seconds > getTimeout()) { remove(key); return null; } return dataDTO.getData(); }
这样,我们的WeakHashMap就可以指定一个过期时间了,而不用等待JVM垃圾回收。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
查看Java的汇编指令
通过javap 命令,可以将字节码文件反编译。如通过下面的命令: javap -c Xxxx.class 而有时候想看某些JDK底层实现,发现反编译得到的代码并没有什么帮助,因此本文介绍如何查看Java的汇编指令,查看Java代码最真实的运行细节。 Java本身提供这个支持,但需要引入而外的包(hsdis-amd64.dylib)。 Mac下: https://github.com/evolvedmicrobe/benchmarks/blob/master/hsdis-amd64.dylib 下载下来后,将其放置到jre lib目录下即可。 查看Java的汇编指令 1、可以使用命令 java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly Main (Main是class文件) 2、在IDEA配置VM options,打印汇编指令,如下图。 -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly 这种方式,在运行程序时,直接在控制台打印汇编指令。 如果遇到: Java HotSpot(TM)...
- 下一篇
Javascript对象Oject的强制类型转换
众所周知Javascript作为一种动态类型,弱类型的脚本语言其数据类型在很多时候都会发生类型转换。而这些类型转换往往都是隐式的,这让我们在使用Js的时候会产生许多麻烦。而Js的基础数据类型的转换在此文中不过多阐述,主要记录Js对象数据类型的转换。笔者由于比较菜,若有写的不对的地方欢迎大佬在下方留言指正。 1.Number强制转换对象 let a={name:123}; console.log(Number(a)); 我们先简单的声明一个对象,并用Number()对其进行强制类型转换 运行结果如下: 那么我们来分析一下对象经过强制类型转换为什么会变成NaN? 在这里就不得不提到Js对象所带有的两个方法,valueOf以及toString。 我们先说一下valueOf这个方法: JavaScript调用valueOf方法将对象转换为原始值。你很少需要自己调用valueOf方法;当遇到要预期的原始值的对象时,JavaScript会自动调用它。 默认情况下,valueOf方法由Object后面的每个对象继承。 每个内置的核心对象都会覆盖此方法以返回适当的值。如果对象没有原始值,则valueO...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Red5直播服务器,属于Java语言的直播服务器
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Hadoop3单机部署,实现最简伪集群
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2更换Tomcat为Jetty,小型站点的福音