java 手写 jvm高性能缓存,键值对存储,队列存储,存储超时设置

缓存接口

 1 package com.ws.commons.cache;
 2
 3 import java.util.function.Function;
 4
 5 public interface ICache {
 6
 7     void expire(String key, int timeOutSecond);
 8
 9     void leftPush(String key, Object value);
10
11     void rightPush(String key, Object value);
12
13     void rightPush(String key, Object value, int timeOutSecond);
14
15     <T> T rightPop(String key);
16
17     <T> T leftPop(String key);
18
19     public <T> T computeIfAbsent(String key, int outSecond, Function<String, Object> mappingFunction);
20
21     void put(String key, Object value);
22
23     void put(String key, Object value, int timeOutSecond);
24
25     boolean putIfAbsent(String key, Object value);
26
27     boolean putIfAbsent(String key, Object value, int timeOutSecond);
28
29     <T> T get(String key);
30
31     boolean hasKey(String key);
32
33     void remove(String key);
34
35     <T> T removeAndGet(String key);
36 }

View Code

实现类

  1 package com.ws.commons.cache;
  2
  3 import java.time.LocalDateTime;
  4 import java.time.format.DateTimeFormatter;
  5 import java.util.Iterator;
  6 import java.util.Map;
  7 import java.util.Map.Entry;
  8 import java.util.concurrent.ConcurrentLinkedDeque;
  9 import java.util.concurrent.ExecutorService;
 10 import java.util.concurrent.Executors;
 11 import java.util.concurrent.atomic.AtomicInteger;
 12 import java.util.function.Function;
 13
 14 import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
 15 import com.googlecode.concurrentlinkedhashmap.Weighers;
 16 import com.ws.commons.tool.ThreadTool;
 17
 18 /**
 19  * 本地高性能缓存
 20  *
 21  * @author 尘无尘
 22  *
 23  */
 24 public class LocalCache implements ICache {
 25
 26     private static LocalCache staticInstance;
 27
 28     public static LocalCache instance() {
 29         if (staticInstance != null) {
 30             return staticInstance;
 31         } else {
 32             synchronized (LocalCache.class) {
 33                 if (staticInstance != null) {
 34                     return staticInstance;
 35                 }
 36                 staticInstance = new LocalCache();
 37                 return staticInstance;
 38             }
 39         }
 40     }
 41
 42     private LocalCache() {
 43     }
 44
 45     /**
 46      * 存储最大数据数量,超出该数据量时,删除最新存储的数据
 47      */
 48     private static final int MAXCOUNT = 2000;
 49
 50     /**
 51      * 缓存实例
 52      */
 53     private static final Map<String, Object> INSTANCE =new ConcurrentLinkedHashMap.Builder<String, Object>()
 54             .maximumWeightedCapacity(MAXCOUNT). weigher(Weighers.singleton()).initialCapacity(100).build();
 55
 56     /**
 57      * 缓存KEY 存储时间记录
 58      */
 59     private static final Map<String, Long> KEY_TIME_INSTANCE = new ConcurrentLinkedHashMap.Builder<String, Long>()
 60             .maximumWeightedCapacity(MAXCOUNT). weigher(Weighers.singleton()).initialCapacity(100).build();
 61
 62     /**
 63      * 时间格式化对象
 64      */
 65     public static final DateTimeFormatter yyyyMMddHHmmss_FMT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
 66
 67
 68     /**
 69      * 清理缓存线程,防止频繁的缓存清理 创建线程消耗性能
 70      */
 71     private static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool();
 72
 73     /**
 74      * 清理缓存时线程做的锁
 75      */
 76     private static final AtomicInteger TREAM_CACHE_LOCK = new AtomicInteger(0);
 77
 78     /**
 79      * 缓存清理 轮询一圈等待时长
 80      */
 81     private static final int TRIM_INTERIM = 2000;
 82
 83     /**
 84      * 队列存储,在末尾添加元素
 85      *
 86      * @param key
 87      * @param value
 88      * @param outSecond 保存时间(秒),超出时间,被清除
 89      */
 90     @SuppressWarnings("unchecked")
 91     @Override
 92     public void rightPush(String key, Object value, int outSecond) {
 93         ConcurrentLinkedDeque<Object> linkList = (ConcurrentLinkedDeque<Object>) INSTANCE.get(key);
 94         if (linkList == null) {
 95             linkList = new ConcurrentLinkedDeque<>();
 96             INSTANCE.put(key, linkList);
 97         }
 98         KEY_TIME_INSTANCE.put(key,
 99                 Long.parseLong(LocalDateTime.now().plusSeconds(outSecond).format(yyyyMMddHHmmss_FMT)));
100         linkList.offer(value);
101         LocalCache.streamInstance();
102     }
103
104     /**
105      * 队列存储,在末尾添加元素
106      *
107      * @param key
108      * @param value
109      */
110     @SuppressWarnings("unchecked")
111     @Override
112     public void rightPush(String key, Object value) {
113         ConcurrentLinkedDeque<Object> linkList = (ConcurrentLinkedDeque<Object>) INSTANCE.get(key);
114         if (linkList == null) {
115             linkList = new ConcurrentLinkedDeque<>();
116             INSTANCE.putIfAbsent(key, linkList);
117         }
118         linkList.offer(value);
119         LocalCache.streamInstance();
120     }
121
122     /**
123      * 队列存储,在开头添加元素
124      *
125      * @param key
126      * @param value
127      */
128     @SuppressWarnings("unchecked")
129     @Override
130     public void leftPush(String key, Object value) {
131         ConcurrentLinkedDeque<Object> linkList = (ConcurrentLinkedDeque<Object>) INSTANCE.get(key);
132         if (linkList == null) {
133             linkList = new ConcurrentLinkedDeque<>();
134             INSTANCE.putIfAbsent(key, linkList);
135         }
136         linkList.offerFirst(value);
137         LocalCache.streamInstance();
138     }
139
140     /**
141      * 删除队列的最后一个元素
142      *
143      * @param key
144      * @return
145      */
146     @SuppressWarnings("unchecked")
147     @Override
148     public <T> T rightPop(String key) {
149         ConcurrentLinkedDeque<Object> linkList = (ConcurrentLinkedDeque<Object>) INSTANCE.get(key);
150         if (linkList == null) {
151             return null;
152         }
153         return (T) linkList.pollLast();
154     }
155
156     /**
157      * 删除队列的第一个元素
158      *
159      * @param key
160      * @return
161      */
162     @SuppressWarnings("unchecked")
163     @Override
164     public <T> T leftPop(String key) {
165         ConcurrentLinkedDeque<Object> linkList = (ConcurrentLinkedDeque<Object>) INSTANCE.get(key);
166         if (linkList == null) {
167             return null;
168         }
169         return (T) linkList.pollFirst();
170     }
171
172     /**
173      *
174      * @param key
175      * @param outSecond 保存时间(秒),超出时间,被清除
176      * @param value
177      */
178     @SuppressWarnings("unchecked")
179     @Override
180     public <T>T computeIfAbsent(String key, int outSecond, Function<String, Object> mappingFunction) {
181         T t=(T) INSTANCE.computeIfAbsent(key, mappingFunction);
182         KEY_TIME_INSTANCE.putIfAbsent(key,
183                 Long.parseLong(LocalDateTime.now().plusSeconds(outSecond).format(yyyyMMddHHmmss_FMT)));
184         LocalCache.streamInstance();
185         return t;
186     }
187
188     /**
189      *
190      * @param key
191      * @param value
192      */
193     @Override
194     public void put(String key, Object value) {
195         INSTANCE.put(key, value);
196     }
197
198     /**
199      *
200      * @param key
201      * @param value
202      * @param outSecond 保存时间(秒),超出时间,被清除
203      */
204     @Override
205     public void put(String key, Object value, int outSecond) {
206         INSTANCE.put(key, value);
207         KEY_TIME_INSTANCE.put(key,
208                 Long.parseLong(LocalDateTime.now().plusSeconds(outSecond).format(yyyyMMddHHmmss_FMT)));
209         LocalCache.streamInstance();
210     }
211
212     /**
213      *
214      * @param key
215      * @param value
216      * @return
217      */
218     @Override
219     public boolean putIfAbsent(String key, Object value) {
220         Object result = null;
221         result = INSTANCE.putIfAbsent(key, value);
222         LocalCache.streamInstance();
223         return result == null;
224     }
225
226     /**
227      *
228      * @param key
229      * @param value
230      * @param outSecond 保存时间(秒),超出时间,被清除
231      * @return
232      */
233     @Override
234     public boolean putIfAbsent(String key, Object value, int outTimeSecond) {
235         Object result = null;
236         result = INSTANCE.putIfAbsent(key, value);
237         KEY_TIME_INSTANCE.putIfAbsent(key,
238                 Long.parseLong(LocalDateTime.now().plusSeconds(outTimeSecond).format(yyyyMMddHHmmss_FMT)));
239         LocalCache.streamInstance();
240         return result == null;
241     }
242
243     /**
244      * 获取缓存
245      *
246      * @param key
247      * @return
248      */
249     @SuppressWarnings("unchecked")
250     @Override
251     public <T> T get(String key) {
252         T value = (T) INSTANCE.get(key);
253         if (value == null) {
254             return null;
255         }
256         if (LocalCache.isTimeOut(key)) {
257             INSTANCE.remove(key);
258             KEY_TIME_INSTANCE.remove(key);
259             return null;
260         } else {
261             return value;
262         }
263     }
264
265     @Override
266     public void expire(String key, int timeOutSecond) {
267         KEY_TIME_INSTANCE.put(key,
268                 Long.parseLong(LocalDateTime.now().plusSeconds(timeOutSecond).format(yyyyMMddHHmmss_FMT)));
269     }
270
271     /**
272      * 是否含有
273      *
274      * @param key
275      * @return
276      */
277     @Override
278     public boolean hasKey(String key) {
279         return INSTANCE.containsKey(key);
280     }
281
282     /**
283      * 删除
284      *
285      * @param id
286      * @return
287      */
288     @Override
289     public void remove(String key) {
290         INSTANCE.remove(key);
291     }
292
293     /**
294      * 删除并返回
295      *
296      * @param id
297      * @return
298      */
299     @SuppressWarnings("unchecked")
300     @Override
301     public <T> T removeAndGet(String key) {
302         return (T) INSTANCE.remove(key);
303     }
304
305     /**
306      * 整理缓存:<br>
307      * 整理的缓存的线程只能一个,节约资源开销<br>
308      * TRIM_INTERIM<br>
309      */
310     private static void streamInstance() {
311
312         if (TREAM_CACHE_LOCK.incrementAndGet() > 1) {
313             return;
314         }
315         THREAD_POOL.execute(() -> {
316             long now = Long.parseLong(LocalDateTime.now().format(yyyyMMddHHmmss_FMT));
317             do {
318                 /*
319                  * 1、超时缓存清除
320                  */
321                 Iterator<Entry<String, Object>> instanceIt = INSTANCE.entrySet().iterator();
322                 while (instanceIt.hasNext()) {
323                     String key = instanceIt.next().getKey();
324                     if (LocalCache.isTimeOut(key, now)) {
325                         instanceIt.remove();
326                         KEY_TIME_INSTANCE.remove(key);
327                     }
328                 }
329
330 //                /*
331 //                 * 2、 超容量,从首位开始清除
332 //                 */
333 //                if (INSTANCE.size() > MAXCOUNT) {
334 //                    List<String> tempList = new ArrayList<>();
335 //                    for (Entry<String, Object> en : INSTANCE.entrySet()) {
336 //                        tempList.add(en.getKey());
337 //                        if (INSTANCE.size() - tempList.size() <= MAXCOUNT) {
338 //                            tempList.forEach(e -> {
339 //                                INSTANCE.remove(e);
340 //                                KEY_TIME_INSTANCE.remove(e);
341 //                            });
342 //                            break;
343 //                        }
344 //                    }
345 //                }
346
347                 ThreadTool.sleep(TRIM_INTERIM);
348                 now = Long.valueOf(LocalDateTime.now().format(yyyyMMddHHmmss_FMT));
349             } while (!INSTANCE.isEmpty());
350             TREAM_CACHE_LOCK.set(0);
351         });
352     }
353
354     /**
355      * 判断key对比当前时间是否超时
356      *
357      * @param key
358      * @return
359      */
360     private static boolean isTimeOut(String key) {
361         long now = Long.parseLong(LocalDateTime.now().format(yyyyMMddHHmmss_FMT));
362         return LocalCache.isTimeOut(key, now);
363     }
364
365     /**
366      *
367      * 判断key对比now是否超时
368      *
369      * @param key
370      * @param now
371      * @return
372      */
373     private static boolean isTimeOut(String key, long now) {
374         Long saveTime = KEY_TIME_INSTANCE.get(key);
375         return saveTime == null || saveTime < now;
376     }
377 }

java 手写 jvm高性能缓存相关推荐

  1. 大牛程序员用Java手写JVM:刚好够运行 HelloWorld

    专注于Java领域优质技术号,欢迎关注 作者:老曹撸代码 1. 前言 没错这又是一篇介绍 JVM 的文章,这类文章网上已经很多,不同角度.不同深度.不同广度,也都不乏优秀的.为什么还要来一篇?首先对于 ...

  2. 【手写JVM专栏】一、带你用Java实现JVM-开篇

    hello,小伙伴们好,我是江湖人送外号[道格牙]的子牙老师. 手写JVM小班一期已经结束了,二期的课也备得差不多了,现在稍微有点时间了,准备给大家出套教程:用Java带你手写JVM. 因为我的手写J ...

  3. Java 手写一个SQL分页

    Java手写一个类似PageHelper的分页SQL 目前分页插件众所周知的莫过于和mybatis完美融合的PageHelper了,简单两行代码就实现了sql分页,配合PageInfo类,将数据总数量 ...

  4. Java手写线程池-第一代(原创)

    个人简介 作者是一个来自河源的大三在校生,以下笔记都是作者自学之路的一些浅薄经验,如有错误请指正,将来会不断的完善笔记,帮助更多的Java爱好者入门. 文章目录 个人简介 Java手写线程池(第一代) ...

  5. Java 手写签字去除背景 背景透明

    Java 手写签字去除背景 背景透明 /*** 白底照片去除白底 形成透明底图片* @param file 需要去除背景的图片* @param Path 去除背景后保存图片的路径* @return t ...

  6. java手写实现BST

    难易程度:★★★ 重要性:★★★★★ 今日头条的面试中有过要求:手写实现BST import java.util.*;public class MyBSTImpl {// BST中的节点TreeNod ...

  7. 纯jsp实现评论功能_自己实现的java手写tomcat

    这是一个java写的模拟tomcat工作原理的demo,是一个极简的tomcat服务器,也是我们培训班(邦邦IT教育)的讲义,是整个j2ee培训的精髓,理解了这个demo其实后面的很多东西都是可以自学 ...

  8. Java手写HashSet

    一:引言 HashSet类继承于 Set接口 其方法均可被直接调用,不用手写,本篇敲的码是为了熟悉底层原理,HashMap的特点:无序,无重复.其底层用的也是map<key,value>容 ...

  9. Java手写Hashmap(HashMap的基本用法)

    一:引言 HashMap是Map的实现类,其方法都可以继承Map,不用手写,本篇只是为了了解底层代码和复习java基础敲得码 二:上码 package cn.wyj.two;public class ...

最新文章

  1. javascript Windows对象(BOM)
  2. 双拼输入法键位图_谈谈小鹤双拼入门(1)
  3. 通过一个简单的例子,了解如何单步调试 Cypress 代码
  4. DotLiquid模板引擎简介
  5. 搭建github服务器_搭建一个属于自己的公网博客
  6. 安卓团课快进_青年大学习网上主题团课第十季第七期答案
  7. 点击按钮刷新_Chrome扩展推荐:抢票太累?后台监视网页,页面自动刷新和提醒...
  8. WebLogic UniversalExtractor反序列化漏洞(CVE-2020-14645)的复现和分析
  9. STL模板之vector与sort的使用
  10. .Net 读取xml
  11. 数据--第20课-递归的应用实战二
  12. java jaas_JAAS(auth和rbac哪个好)
  13. 论文精读——基于演化动力学的复杂网络中带阈值雪堆博弈模型研究
  14. mt管理器小白破解之路-基础篇第一课
  15. 微信小程序-2-微信开发者工具介绍
  16. word文档中实现目录索引中标题加粗,前导符和页码不加粗
  17. 2022年8种高级威胁预测出炉、FBI就零日漏洞发出警报|11月22日全球网络安全热点
  18. 成分句法分析与依存句法分析
  19. 最小生成树算法之Kruskal算法
  20. 四阶幻方c语言编程,13年 第四届 蓝桥杯C语言C组 第4题 幻方填空

热门文章

  1. php导出csv文件乱码问题解决方法
  2. jquery user interface
  3. redis——redis简介及基本交互方法
  4. E: Some index files failed to download. They have been ignored, or old ones used instead.解决方案
  5. 机器学习速成课程 | 练习 | Google Development——编程练习:特征集
  6. SpringBoot—@ComponentScan注解过滤排除某个类
  7. linux 命令行使用wget下载百度云资源
  8. Ubuntu 16.04 开机自动锁定数字键盘
  9. Ubuntu 16.04 安装phpmyadmin以及注意事项
  10. 公司的年度汇报怎么写 年底述职报告写法