首页 > 编程语言 > 详细

java 手写 jvm高性能缓存

时间:2019-07-02 18:05:55      阅读:207      评论:0      收藏:0      [点我收藏+]

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

技术分享图片

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

 

java 手写 jvm高性能缓存

原文:https://www.cnblogs.com/abab/p/11121773.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!