zoukankan      html  css  js  c++  java
  • java手写多级缓存

    多级缓存实现类,时间有限,该类未抽取接口,目前只支持两级缓存:JVM缓存(实现 请查看上一篇:java 手写JVM高性能缓存)、redis缓存(在spring 的 redisTemplate 基础实现)

    package com.ws.commons.cache;
    
    import java.util.function.Supplier;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.ws.commons.tool.ThreadTool;
    
    /**
     * 多级缓存实现
     * 
     * @author 尘无尘
     *
     */
    public class MultilevelCache {
        private static final Logger LOGGER = LoggerFactory.getLogger(MultilevelCache.class);
    
        private MultilevelCache() {
        }
    
        private static final ICache FIRST_LEVE_LCACHE = LocalCache.instance();
        private static ICache secondCache;
    
        private static final String LOCK_PREFIX = "MUILCACHE_LOCK:";
    
        public static synchronized void init(ICache secondCache) {
            if (MultilevelCache.secondCache == null) {
                MultilevelCache.secondCache = secondCache;
                LOGGER.info("开启二级缓存,secondCache:{}", secondCache);
            }
        }
    
        public static void put(String key, Object value, int timeOutSecond) {
            if (secondCache != null) {
                secondCache.put(key, value, timeOutSecond);
                FIRST_LEVE_LCACHE.put(key, value, cmpFirstCacheTimeOutSecond(timeOutSecond));
            } else {
                FIRST_LEVE_LCACHE.put(key, value, timeOutSecond);
            }
        }
    
        /**
         * 提供数据,并缓存
         * 
         * @param key
         * @param supplier
         * @return
         */
        public static <T> T computeIfAbsent(String key, Supplier<T> supplier) {
            T data = FIRST_LEVE_LCACHE.get(key);
            if (data == null && secondCache != null) {
                data = secondCache.get(key);
            }
            if (data != null) {
                return data;
            }
    
            synchronized (ThreadTool.buildLock(LOCK_PREFIX, key)) {
                data = FIRST_LEVE_LCACHE.get(key);
                if (data == null && secondCache != null) {
                    data = secondCache.get(key);
                }
                if (data != null) {
                    return data;
                }
    
                data = supplier.get();
                if (secondCache != null) {
                    secondCache.put(key, data);
                    FIRST_LEVE_LCACHE.put(key, data, 60);
                } else {
                    FIRST_LEVE_LCACHE.put(key, data);
                }
            }
            return data;
        }
    
        /**
         * 提供数据,并缓存一定的时间
         * 
         * @param key
         * @param timeOutSecond
         * @param supplier
         * @return
         */
        public static <T> T computeIfAbsent(String key, int timeOutSecond, Supplier<T> supplier) {
            T data = FIRST_LEVE_LCACHE.get(key);
            if (data == null && secondCache != null) {
                data = secondCache.get(key);
            }
            if (data != null) {
                return data;
            }
            synchronized (ThreadTool.buildLock(LOCK_PREFIX, key)) {
                data = FIRST_LEVE_LCACHE.get(key);
                if (data == null && secondCache != null) {
                    data = secondCache.get(key);
                }
                if (data != null) {
                    return data;
                }
                data = supplier.get();
                if (secondCache != null) {
                    secondCache.put(key, data, timeOutSecond);
                    FIRST_LEVE_LCACHE.put(key, data, cmpFirstCacheTimeOutSecond(timeOutSecond));
                } else {
                    FIRST_LEVE_LCACHE.put(key, data, timeOutSecond);
                }
    
            }
            return data;
        }
    
        public static <T> T removeAndGet(String key) {
            T data = null;
            if (secondCache != null) {
                data = secondCache.removeAndGet(key);
            }
            T data2 = FIRST_LEVE_LCACHE.removeAndGet(key);
            if (data == null) {
                data = data2;
            }
            return data;
        }
    
        public static void remove(String key) {
            if (secondCache != null) {
                secondCache.remove(key);
            }
            FIRST_LEVE_LCACHE.remove(key);
        }
    
        public static <T> T get(String key) {
            T data = FIRST_LEVE_LCACHE.get(key);
            if (data == null && secondCache != null) {
                data = secondCache.get(key);
            }
            return data;
        }
    
        public static void expire(String key, int timeOutSecond) {
            FIRST_LEVE_LCACHE.expire(key, timeOutSecond);
            if (secondCache != null) {
                secondCache.expire(key, timeOutSecond);
            }
        }
    
        private static int cmpFirstCacheTimeOutSecond(int timeOutSecond) {
            if (timeOutSecond > 60) {
                return 60;
            } else if (timeOutSecond > 30) {
                return timeOutSecond / 2;
            }
            return timeOutSecond;
        }
    }
  • 相关阅读:
    NO12 useradd-passwd-uname-hostname命令-上传rz下载sz-批量部署- Linux用户相关操作
    NO11 SSH故障排查思路和netstat命令
    NO10 查看Linux操作系统-版本-内核-Linux分区
    NO9 Linux快捷键整理及最常用命令
    NO8 find结合sed查找替换企业案例多方法精讲&命令总结!
    NO7 利用三剑客awk-grep-sed-head-tail等7种方法实践
    python 对比图片相似度
    MonkeyRunner 实现自动点击截屏后与本地图库进行对比输出
    monkeyrunner对比屏幕局部图像.getSubImage()
    锤子便签的 monkeyrunner 测试脚本(转)
  • 原文地址:https://www.cnblogs.com/abab/p/11139477.html
Copyright © 2011-2022 走看看