java缓存数据并配置有效时间[通俗易懂]

java缓存数据并配置有效时间[通俗易懂]没有用到redis只是单纯的使用内存存储数据实现的功能:缓存数据并配置有效时间,可设置默认时间自动清除缓存,也可以自己设置。直接上代码:importjava.util.LinkedList;importjava.util.List;importjava.util.Map.Entry;importjava.util.Timer;importjava.util.TimerTask;importjava.util.concurrent.ConcurrentHashMap;publ

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

Jetbrains全系列IDE稳定放心使用

没有用到redis 只是单纯的使用内存存储数据

实现的功能:缓存数据并配置有效时间,可设置默认时间自动清除缓存,也可以自己设置。

直接上代码:

import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

public class TimeExpiredPoolCache {
    private static  long defaultCachedMillis = 10 * 60 * 1000L;//过期时间默认10分钟
    private static long timerMillis = 10 * 60 * 1000L;//定时清理默认10分钟
    /**
     * 对象池
     */
    private static ConcurrentHashMap<String, DataWrapper<?>> dataPool = null;
    /**
     * 对象单例
     */
    private static TimeExpiredPoolCache instance = null;
    private TimeExpiredPoolCache() {
        dataPool = new ConcurrentHashMap<String, DataWrapper<?>>();
    }
    private static synchronized void syncInit() {
        if (instance == null) {
            instance = new TimeExpiredPoolCache();
            initTimer();
        }
    }
    public static TimeExpiredPoolCache getInstance() {
        if (instance == null) {
            syncInit();
        }
        return instance;
    }
    /**
     * 定时器定时清理过期缓存
     */
    private static Timer timer = new Timer();
    private static void initTimer() {
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                try {
                    clearExpiredCaches();
                } catch (Exception e) {
                    //logger.error("clearExpiredCaches error.", e);
                }
            }
        }, timerMillis, timerMillis);
    }

    /**
     * 缓存数据
     * @param key key值
     * @param data 缓存数据
     * @param cachedMillis 过期时间
     * @param dataRenewer 刷新数据
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> T put(String key, T data, long cachedMillis, DataRenewer<T> dataRenewer) throws Exception {
        DataWrapper<T> dataWrapper = (DataWrapper<T>)dataPool.get(key);
        if (data == null && dataRenewer != null) {
            data = dataRenewer.renewData();
        }
        //当重新获取数据为空,直接返回不做put
        if (data == null){
            return null;
        }
        if (dataWrapper != null) {
            //更新
            dataWrapper.update(data, cachedMillis);
        } else {
            dataWrapper = new DataWrapper<T>(data, cachedMillis);
            dataPool.put(key, dataWrapper);
        }
        return data;
    }
    /**
     * 直接设置缓存值和时间
     * @param key
     * @param data
     * @param cachedMillis
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> T put(String key, T data, long cachedMillis) throws Exception{
        DataWrapper<T> dataWrapper = (DataWrapper<T>)dataPool.get(key);
        if (dataWrapper != null) {
            //更新
            dataWrapper.update(data, cachedMillis);
        } else {
            dataWrapper = new DataWrapper<T>(data, cachedMillis);
            dataPool.put(key, dataWrapper);
        }
        return data;
    }
    /**
     * 默认构造时间的缓存数据
     * @param key
     * @param data
     * @param dataRenewer
     * @return
     */
    @Deprecated
    public <T> T put(String key, T data, DataRenewer<T> dataRenewer) throws Exception {
        return put(key, data, defaultCachedMillis, dataRenewer);
    }
    /**
     * 获取缓存
     * @param key
     * @param cachedMillis
     * @param dataRenewer
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> T get(String key, long cachedMillis, DataRenewer<T> dataRenewer) throws Exception {
        DataWrapper<T> dataWrapper = (DataWrapper<T>)dataPool.get(key);
        if (dataWrapper != null && !dataWrapper.isExpired()) {
            return dataWrapper.data;
        }
        return put(key, null, cachedMillis, dataRenewer);
    }
    @SuppressWarnings("unchecked")
    public <T> T get(String key) throws Exception {
        DataWrapper<T> dataWrapper = (DataWrapper<T>)dataPool.get(key);
        if (dataWrapper != null && !dataWrapper.isExpired()) {
            return dataWrapper.data;
        }
        return null;
    }
    /**
     * 清除缓存
     */
    public void clear() {
        dataPool.clear();
    }

    /**
     * 删除指定key的value
     * */
    public void remove(String key){
        dataPool.remove(key);
    }

    /**
     * 数据封装
     */
    private class DataWrapper<T> {
        /**
         * 数据
         */
        private T data;
        /**
         * 到期时间
         */
        private long expiredTime;
        /**
         * 缓存时间
         */
        private long cachedMillis;
        private DataWrapper(T data, long cachedMillis) {
            this.update(data, cachedMillis);
        }
        public void update(T data, long cachedMillis) {
            this.data = data;
            this.cachedMillis = cachedMillis;
            this.updateExpiredTime();
        }
        public void updateExpiredTime() {
            this.expiredTime = System.currentTimeMillis() + cachedMillis;
        }
        /**
         * 数据是否过期
         * @return
         */
        public boolean isExpired() {
            if (this.expiredTime > 0) {
                return System.currentTimeMillis() > this.expiredTime;
            }
            return true;
        }
    }
    /**
     * 数据构造
     */
    public interface DataRenewer<T> {
        public T renewData();
    }

    /**
     * 清除过期的缓存
     */
    private static void clearExpiredCaches() {
        List<String> expiredKeyList = new LinkedList<String>();

        for(Entry<String, DataWrapper<?>> entry : dataPool.entrySet()){
            if (entry.getValue().isExpired()) {
                expiredKeyList.add(entry.getKey());
            }
        }
        for (String key : expiredKeyList) {
            dataPool.remove(key);
        }
    }
	}

测试:

import com.example.demo2.utils.TimeExpiredPoolCache;
import org.springframework.web.bind.annotation.*;

@RestController
public class CacheDemo {

    @RequestMapping(value = "/saveToken", method = RequestMethod.GET)
    public String  saveToken(){
        try {
            TimeExpiredPoolCache.getInstance().put("token","1008611",1000L*30);
            new TimeThread().run();
            return "保存token进入缓冲成功";
        } catch (Exception e) {
            return "保存token进入缓存失败";
        }
    }

    @RequestMapping(value = "/getToken", method = RequestMethod.GET)
    public String  getToken(){
        try {
           // token = String.valueOf(TimeExpiredPoolCache.getInstance().get("token"));
            String   token = TimeExpiredPoolCache.getInstance().get("token");
            if (null!=token){
                return token;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "数据为空................";
    }

    public static class TimeThread implements  Runnable{

        @Override
        public void run() {
            for(int i=30;i>0;i--){
                System.out.println("缓冲倒计时:"+i+" 秒");
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

浏览直接访问 (我这里设置的端口号是8888)
在这里插入图片描述
localhost:8888/saveToken 调用存储token值为1008611,时间为30秒有效
在这里插入图片描述
localhost:8888/getToken 可以获取token值,可以在缓存有效期内和有效期外分别调用,看下缓存值是否存在
在这里插入图片描述
在这里插入图片描述

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

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/185958.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Matlab 2016a 安装包及破解教程

    Matlab 2016a 安装包及破解教程Matlab-Matlab2016a安装破解教程本方法只是研究破解技术所用。如果要使用软件还是要用正版的。Matlab2016a安装包及破解教程百度云分享链接: 链接:https://pan.baidu.com/s/1i6BgD8p    密码:17gg Matlab安装教程: 1、下载文件,得到R2016a_win64.part1.rar、R2016a_…

  • 如何查看tomcat的版本号(文件版本号)

    进入Tomcat/bin目录下,Shift+右键->在此处打开命令提示框,打开命令提示符窗口,输入命令version.bat,就可以看到如下结果哈哈哈,报错了…懵了吧,别急看看错误说明…貌似明白了,再来一次总结:进入Tomcat/bin目录下,Shift+右键->在此处打开命令提示框,打开命令提示符窗口,输入命令version.bat,如果报错,试试输入命令.\v…

  • 使用SpringBoot上传文件并存储至数据库

    使用SpringBoot上传文件并存储至数据库springboot2.2.1.RELEASE <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><…

  • android 应用的证书签名跟系统签名

    android 应用的证书签名跟系统签名作为软件行业的从业者都知道,一款软件的开发过程中肯定会诞生两种版本,即debug版本和release版本,debug版本包含有调试信息,一般来说都要比release版本大,android应用当然也不例外1.证书签名并不是所有的apk文件都能成功安装到安卓设备上,android系统要求只有签名后的apk文件才可以安装,因此我们还要对生成的apk文件进行签名才行在androidstudio中直接运行项目生成的都是测试版debug安装文…

  • 开心农场2激活成功教程版无限金币钥匙_开心农场2乡村度假内购激活成功教程版

    开心农场2激活成功教程版无限金币钥匙_开心农场2乡村度假内购激活成功教程版 最近开心农场非常火,同学用C#模拟鼠标点击操作做了一个小外挂,但是这样做有如下缺点:1、计算机不能做其他事情,2、必须开着浏览器,3、对所有好友点一遍的时间太慢,4、对于开发者来说技术含量低了点,呵呵。 所以我尝试着改进这种实现,我的想法是:不用开启浏览器,直接运行一个应用程序,该程序将自己伪装成一个浏览器,与服务器连接,并发送浇水、除虫等命令。这样,甚至可以使用多线程向服务器发送命令,无需…

  • dedecms系统后台登陆提示用户名密码不存在

    dedecms系统后台登陆提示用户名密码不存在

发表回复

您的电子邮箱地址不会被公开。

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