java 缓存工具类初始化_Java缓存框架

java 缓存工具类初始化_Java缓存框架Java缓存工具类Cache工具类定义

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

Java 缓存工具类 Cache

工具类定义

package com.demo.utils;

import org.springframework.util.StringUtils;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/** * Description: 缓存工具类 * 1.部分方法未验证,如有问题请自行修改 * 2.其他方法请自行添加 * * @Author: zhx & moon hongxu_1234@163.com * @Date: 2022-04-07 20:54 * @version: V1.0.0 */
public class Cache { 
   

    /** * 屏蔽工具类的无参构造 避免工具类被实例化 */
    private Cache(){ 
   }

    /** * 缓存留存期 30min 1H 24H */
    public static final long CACHE_HOLD_TIME_30M = 30 * 60 * 1000L;
    public static final long CACHE_HOLD_TIME_1H = 2 * CACHE_HOLD_TIME_30M;
    public static final long CACHE_HOLD_TIME_24H = 24 * CACHE_HOLD_TIME_1H;
    public static final long CACHE_HOLD_TIME_FOREVER = -1L;

    /** * 缓存容量、最少使用容量 */
    private static final int CACHE_MAX_CAP = 1000;
    private static final int CLEAN_LRU_CAP = 800;

    /** * 缓存当前大小 */
    private static AtomicInteger CACHE_CURRENT_SIZE = new AtomicInteger(0);

    /** * 缓存对象 */
    private static final Map<String,Node> CACHE_MAP = new ConcurrentHashMap<>(CACHE_MAX_CAP);

    /** * 最少使用记录 */
    private static final List<String> LRU_LIST = new LinkedList<>();

    /** * 自动清理标志位 */
    private static volatile boolean CLEAN_RUN_FLAG = false;

    /** * 默认30MIN * @param key * @param val */
    public static void put(String key,Object val){ 
   
        put(key,val,CACHE_HOLD_TIME_30M);
    }

    /** * 添加永久缓存 * @param key * @param val */
    public static void putForever(String key,Object val){ 
   
        put(key,val,CACHE_HOLD_TIME_FOREVER);
    }

    /** * 添加缓存 * @param key * @param val * @param ttlTime */
    public static void put(String key,Object val,long ttlTime){ 
   
        if (!StringUtils.hasLength(key) || null == val){ 
   
            return;
        }
        checkSize();
        updateCacheLru(key);
        CACHE_MAP.put(key,new Node(val,ttlTime));
    }

    /** * 获取缓存信息 * @param key * @param clazz * @param <T> * @return */
    public static <T> T get(String key,Class<T> clazz){ 
   
        if (!StringUtils.hasLength(key) || !CACHE_MAP.containsKey(key)){ 
   
            return null;
        }
        updateCacheLru(key);
        return (T) CACHE_MAP.get(key).getVal();
    }

    /** * 更新最近使用位置 * @param key */
    private static void updateCacheLru(String key){ 
   
        synchronized (LRU_LIST){ 
   
            LRU_LIST.remove(key);
            LRU_LIST.add(0,key);
        }
    }

    /** * 删除,成功则容量-1 * @param key */
    private static boolean remove(String key){ 
   
        Node node = CACHE_MAP.remove(key);
        if (null!=node){ 
   
            CACHE_CURRENT_SIZE.getAndDecrement();
            return true;
        }
        return false;
    }

    /** * 检查是否超过容量,先清理过期,在清理最少使用 */
    private static void checkSize(){ 
   
        if (CACHE_CURRENT_SIZE.intValue() > CACHE_MAX_CAP){ 
   
            deleteTimeOut();
        }
        if (CACHE_CURRENT_SIZE.intValue() > CLEAN_LRU_CAP){ 
   
            deleteLru();
        }
    }

    /** * 删除最久未使用,尾部删除 * 永久缓存不会被清除 */
    private static void deleteLru(){ 
   
        synchronized (LRU_LIST){ 
   
            while (LRU_LIST.size() > CLEAN_LRU_CAP){ 
   
                int lastIndex = LRU_LIST.size() - 1;
                String key = LRU_LIST.get(lastIndex);
                if (!CACHE_MAP.get(key).isForever() && remove(key)){ 
   
                    LRU_LIST.remove(lastIndex);
                }
            }
        }
    }

    /** * 删除过期 */
    private static void deleteTimeOut(){ 
   
        List<String> del = new LinkedList<>();
        for (Map.Entry<String,Node> entry:CACHE_MAP.entrySet()){ 
   
            if (entry.getValue().isExpired()){ 
   
                del.add(entry.getKey());
            }
        }
        for (String k:del){ 
   
            remove(k);
        }
    }

    /** * 缓存是否已存在,过期则删除返回False * @param key * @return */
    public static boolean contains(String key){ 
   
        if (CACHE_MAP.containsKey(key)){ 
   
            if (!CACHE_MAP.get(key).isExpired()){ 
   
                return true;
            }
            if (remove(key)){ 
   
                return false;
            }
            return true;
        }
        return false;
    }

    /** * 清空缓存 */
    public static void clear(){ 
   
        CACHE_MAP.clear();
        CACHE_CURRENT_SIZE.set(0);
        LRU_LIST.clear();
    }

    /** * 重置自动清理标志 * @param flag */
    public static void setCleanRunFlag(boolean flag){ 
   
        CLEAN_RUN_FLAG = flag;
    }

    /** * 自动清理过期缓存 */
    private static void startAutoClean(){ 
   

        if (!CLEAN_RUN_FLAG){ 
   
            setCleanRunFlag(true);
            ScheduledExecutorService scheduledExecutor = new ScheduledThreadPoolExecutor(1);
            scheduledExecutor.scheduleAtFixedRate(()->{ 
   
                try { 
   
                    Cache.setCleanRunFlag(true);
                    while (CLEAN_RUN_FLAG){ 
   
                        Cache.deleteTimeOut();
                    }
                } catch (Exception e) { 
   
                    e.printStackTrace();
                }
            },10,Cache.CACHE_HOLD_TIME_1H, TimeUnit.SECONDS);
        }
    }

    /** * 缓存对象类 */
    public static class Node{ 
   
        /** * 缓存值 */
        private Object val;
        /** * 过期时间 */
        private long ttlTime;

        public Node(Object val,long ttlTime){ 
   
            this.val = val;
            if (ttlTime<0){ 
   
                this.ttlTime = ttlTime;
            }else{ 
   
                this.ttlTime = System.currentTimeMillis() + ttlTime;
            }
        }

        public Object getVal(){ 
   
            return this.val;
        }

        public boolean isExpired(){ 
   
            if (this.ttlTime<0){ 
   
                return false;
            }
            return System.currentTimeMillis() > this.ttlTime;
        }

        public boolean isForever(){ 
   
            if (this.ttlTime<0){ 
   
                return true;
            }
            return false;
        }

    }


}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/186015.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • web面试题及答案_前端html面试题

    web面试题及答案_前端html面试题阅读目录html/cssjavascriptes6vuereactjQuerywebpack、gulp、gruntnodehttpweb安全前端性能浏览器算法相关设计模式正则表达式职业规划参考资料html/css行内元素和块级元素举几个例子?行内元素:span,a,var,em,input,img,img,textarea,var,em,s……

    2022年8月29日
    9
  • acwing-91. 最短Hamilton路径(状态压缩dp)

    acwing-91. 最短Hamilton路径(状态压缩dp)给定一张 n 个点的带权无向图,点从 0∼n−1 标号,求起点 0 到终点 n−1 的最短 Hamilton 路径。Hamilton 路径的定义是从 0 到 n−1 不重不漏地经过每个点恰好一次。输入格式第一行输入整数 n。接下来 n 行每行 n 个整数,其中第 i 行第 j 个整数表示点 i 到 j 的距离(记为 a[i,j])。对于任意的 x,y,z,数据保证 a[x,x]=0,a[x,y]=a[y,x] 并且 a[x,y]+a[y,z]≥a[x,z]。输出格式输出一个整数,表示最短 Ha

    2022年8月9日
    6
  • Web后端基础知识[通俗易懂]

    Web后端基础知识[通俗易懂]文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结前言提示:以下是本篇文章正文内容,下面案例可供参考一、pandas是什么?示例:pandas是基于NumPy的一种工具,该工具是为了解决数据分析任务而创建的。二、使用步骤1.引入库代码如下(示例):importnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltimportseabornassnsimportwarnings

    2022年6月16日
    32
  • 水果篮一般装几种水果_one step closer水果篮子

    水果篮一般装几种水果_one step closer水果篮子904.水果成篮题目描述题目链接:904水果成蓝你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组fruits表示,其中fruits[i]是第i棵树上的水果种类。你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:你只有两个篮子,并且每个篮子只能装单一类型的水果。每个篮子能够装的水果总量没有限制。你可以选择任意一棵树开始采摘,你必须从每棵树(包括开始采摘的树)上恰好摘一个水果。采摘的水果应当符合篮子中的水果类型。

    2022年9月2日
    8
  • 0~9迷你上标小数字复制_下标1

    0~9迷你上标小数字复制_下标1A⁰¹²³⁴⁵⁶⁷⁸⁹B₀₁₂₃₄₅₆₇₈₉

    2022年9月30日
    4
  • js 除法 取整「建议收藏」

    js 除法 取整「建议收藏」1.丢弃小数部分,保留整数部分 js:parseInt(7/2) 2.向上取整,有小数就整数部分加1 js:Math.ceil(7/2) 3,四舍五入. js:Math.round(7/2) 4,向下取整 js:Math.floor(7/2)都是JS内置对象

    2022年6月21日
    98

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号