zoukankan      html  css  js  c++  java
  • java 手写 jvm高性能缓存

    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 }
  • 相关阅读:
    钉钉 LDAP
    OpenLDAP 密码策略与审计控制
    Active Directory LDAP DingDing
    Linux kill 命令 java
    Memory Analyzer 与 Java VM 版本支持问题
    java.lang.Thread.State
    稻盛和夫 活法 人生公式
    [领导力/管理]一句话说带团队
    把某个公司git项目迁移到gitee的步骤
    Protocol Buffers  |  Google Developers
  • 原文地址:https://www.cnblogs.com/abab/p/11121773.html
Copyright © 2011-2022 走看看