java 手写 jvm高性能缓存
程序员文章站
2022-07-09 21:18:19
java 手写 jvm高性能缓存,键值对存储,队列存储,存储超时设置 缓存接口 package com.ws.commons.cache; public interface ICache { void expire(String key, int timeOutSecond); void leftP ......
java 手写 jvm高性能缓存,键值对存储,队列存储,存储超时设置
缓存接口
package com.ws.commons.cache; public interface icache { void expire(string key, int timeoutsecond); void leftpush(string key, object value); void rightpush(string key, object value); void rightpush(string key, object value, int timeoutsecond); <t> t rightpop(string key); <t> t leftpop(string key); void put(string key, object value); void put(string key, object value, int timeoutsecond); boolean putifabsent(string key, object value); boolean putifabsent(string key, object value, int timeoutsecond); <t> t get(string key); boolean haskey(string key); void remove(string key); <t> t removeandget(string key); }
实现类
package com.ws.commons.cache; import java.time.localdatetime; import java.time.format.datetimeformatter; import java.util.arraylist; import java.util.collections; import java.util.iterator; import java.util.linkedhashmap; import java.util.list; import java.util.map; import java.util.map.entry; import java.util.concurrent.concurrentlinkeddeque; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.concurrent.atomic.atomicinteger; import com.ws.commons.tool.threadtool; /** * 本地高性能缓存 * * @author 尘无尘 * */ public class localcache implements icache { private static localcache staticinstance; public static localcache instance() { if (staticinstance != null) { return staticinstance; } else { synchronized (localcache.class) { if (staticinstance != null) { return staticinstance; } staticinstance = new localcache(); return staticinstance; } } } private localcache() { } /** * 缓存实例 */ private static final map<string, object> instance = collections.synchronizedmap(new linkedhashmap<>()); /** * 缓存key 存储时间记录 */ private static final map<string, long> key_time_instance = collections.synchronizedmap(new linkedhashmap<>()); /** * 时间格式化对象 */ public static final datetimeformatter yyyymmddhhmmss_fmt = datetimeformatter.ofpattern("yyyymmddhhmmss"); /** * 存储最大数据数量,超出该数据量时,删除最新存储的数据 */ private static final int maxcount = 10000; /** * 清理缓存线程,防止频繁的缓存清理 创建线程消耗性能 */ private static final executorservice thread_pool = executors.newcachedthreadpool(); /** * 清理缓存时线程做的标记 */ private static final atomicinteger tream_cache_flag = new atomicinteger(0); /** * 缓存清理 轮询一圈等待时长 */ private static final int trim_interim = 2000; /** * 队列存储,在末尾添加元素 * * @param key * @param value * @param outsecond 保存时间(秒),超出时间,被清除 */ @suppresswarnings("unchecked") @override public void rightpush(string key, object value, int outsecond) { concurrentlinkeddeque<object> linklist = (concurrentlinkeddeque<object>) instance.get(key); if (linklist == null) { linklist = new concurrentlinkeddeque<>(); instance.put(key, linklist); } key_time_instance.put(key, long.parselong(localdatetime.now().plusseconds(outsecond).format(yyyymmddhhmmss_fmt))); linklist.offer(value); localcache.streaminstance(); } /** * 队列存储,在末尾添加元素 * * @param key * @param value */ @suppresswarnings("unchecked") @override public void rightpush(string key, object value) { concurrentlinkeddeque<object> linklist = (concurrentlinkeddeque<object>) instance.get(key); if (linklist == null) { linklist = new concurrentlinkeddeque<>(); instance.putifabsent(key, linklist); } linklist.offer(value); localcache.streaminstance(); } /** * 队列存储,在开头添加元素 * * @param key * @param value */ @suppresswarnings("unchecked") @override public void leftpush(string key, object value) { concurrentlinkeddeque<object> linklist = (concurrentlinkeddeque<object>) instance.get(key); if (linklist == null) { linklist = new concurrentlinkeddeque<>(); instance.putifabsent(key, linklist); } linklist.offerfirst(value); localcache.streaminstance(); } /** * 删除队列的最后一个元素 * * @param key * @return */ @suppresswarnings("unchecked") @override public <t> t rightpop(string key) { concurrentlinkeddeque<object> linklist = (concurrentlinkeddeque<object>) instance.get(key); if (linklist == null) { return null; } return (t) linklist.polllast(); } /** * 删除队列的第一个元素 * * @param key * @return */ @suppresswarnings("unchecked") @override public <t> t leftpop(string key) { concurrentlinkeddeque<object> linklist = (concurrentlinkeddeque<object>) instance.get(key); if (linklist == null) { return null; } return (t) linklist.pollfirst(); } /** * * @param key * @param value */ @override public void put(string key, object value) { instance.put(key, value); localcache.streaminstance(); } /** * * @param key * @param value * @param outsecond 保存时间(秒),超出时间,被清除 */ @override public void put(string key, object value, int outsecond) { instance.put(key, value); key_time_instance.put(key, long.parselong(localdatetime.now().plusseconds(outsecond).format(yyyymmddhhmmss_fmt))); localcache.streaminstance(); } /** * * @param key * @param value * @return */ @override public boolean putifabsent(string key, object value) { object result = null; result = instance.putifabsent(key, value); localcache.streaminstance(); return result == null; } /** * * @param key * @param value * @param outsecond 保存时间(秒),超出时间,被清除 * @return */ @override public boolean putifabsent(string key, object value, int outtimesecond) { object result = null; result = instance.putifabsent(key, value); key_time_instance.putifabsent(key, long.parselong(localdatetime.now().plusseconds(outtimesecond).format(yyyymmddhhmmss_fmt))); localcache.streaminstance(); return result == null; } /** * 获取缓存 * * @param key * @return */ @suppresswarnings("unchecked") @override public <t> t get(string key) { t value = (t) instance.get(key); if (value == null) { return null; } if (localcache.istimeout(key)) { instance.remove(key); key_time_instance.remove(key); return null; } else { return value; } } @override public void expire(string key, int timeoutsecond) { key_time_instance.put(key, long.parselong(localdatetime.now().plusseconds(timeoutsecond).format(yyyymmddhhmmss_fmt))); } /** * 是否含有 * * @param key * @return */ @override public boolean haskey(string key) { return instance.containskey(key); } /** * 删除 * * @param id * @return */ @override public void remove(string key) { instance.remove(key); } /** * 删除并返回 * * @param id * @return */ @suppresswarnings("unchecked") @override public <t> t removeandget(string key) { return (t) instance.remove(key); } /** * 整理缓存:<br> * 整理的缓存的线程只能一个,节约资源开销<br> * trim_interim<br> */ private static void streaminstance() { if (tream_cache_flag.incrementandget() > 1) { return; } thread_pool.execute(() -> { long now = long.parselong(localdatetime.now().format(yyyymmddhhmmss_fmt)); do { /* * 1、超时缓存清除 */ iterator<entry<string, object>> instanceit = instance.entryset().iterator(); while (instanceit.hasnext()) { string key = instanceit.next().getkey(); if (localcache.istimeout(key, now)) { instanceit.remove(); key_time_instance.remove(key); } } /* * 2、 超容量,从首位开始清除 */ if (instance.size() > maxcount) { list<string> templist = new arraylist<>(); for (entry<string, object> en : instance.entryset()) { templist.add(en.getkey()); if (instance.size() - templist.size() <= maxcount) { templist.foreach(e -> { instance.remove(e); key_time_instance.remove(e); }); break; } } } threadtool.sleep(trim_interim); now = long.valueof(localdatetime.now().format(yyyymmddhhmmss_fmt)); } while (!instance.isempty()); tream_cache_flag.set(0); }); } /** * 判断key对比当前时间是否超时 * * @param key * @return */ private static boolean istimeout(string key) { long now = long.parselong(localdatetime.now().format(yyyymmddhhmmss_fmt)); return localcache.istimeout(key, now); } /** * * 判断key对比now是否超时 * * @param key * @param now * @return */ private static boolean istimeout(string key, long now) { long savetime = key_time_instance.get(key); return savetime == null || savetime < now; } }
上一篇: MacOS VSCode 安装 GO 插件失败问题解决
下一篇: react 实现评分组件