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值,可以在缓存有效期内和有效期外分别调用,看下缓存值是否存在
在这里插入图片描述
在这里插入图片描述

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

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

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


相关推荐

  • Ubuntu创建软连接[通俗易懂]

    Ubuntu创建软连接[通俗易懂]Ubuntu创建软连接建立软连接ln-s原目录删除软连接sudorm或者强制删除-rf创建软连接ln-s源地址目的地址列如:Ubuntu文件系统rootfs_dir软连接到/home/lp目录下ln-s/opt/Linux/root_dir/home/lp/roo_dir就OK了…

    2022年9月30日
    4
  • ProgressDialog总结

    ProgressDialog总结ProgressDialog的使用 ProgressDialog继承自AlertDialog,AlertDialog继承自Dialog,实现DialogInterface接口。 ProgressDialog的创建方式有两种,一种是newDialog,一种是调用Dialog的静态方法Dialog.show()。 //方式一:newDialog finalProgr…

    2022年7月14日
    20
  • 小米的创新发展模式_小米生态链模式简介

    小米的创新发展模式_小米生态链模式简介自从雷军召开小米手机发布会后,小米手机是否能做成,销量多少就成为业界一大话题。小米手机的关键词一度成为百度十大热门关键词。这一现象在产品界恐怕仅有苹果的iPhone才有此殊荣。 但业界绝大部分人士不看好,特别是手机界专业人士。最近小米手机又传出零配件供应问题,专业人士更是质疑声一片。做软件的到底不会做硬件,互联网销售在手机领域不行的论断不绝于耳。而形成反差的是,在市场上小米手机的预订却是火热异

    2025年11月27日
    5
  • 【无标题】ubuntu 18.04安装edge浏览器「建议收藏」

    【无标题】ubuntu 18.04安装edge浏览器「建议收藏」ubuntu18.04安装edge浏览器第一步:sudoaptupdatesudoaptinstallsoftware-properties-commonapt-transport-httpswget第二步,使用以下命令导入MicrosoftGPG密钥wget:wget-qhttps://packages.microsoft.com/keys/microsoft.asc-O-|sudoapt-keyadd-第三步,并通过键入以下命令启用Edge浏览器存储库

    2022年7月21日
    20
  • 谈谈privoxy:关于广告过滤和自动代理切换

    谈谈privoxy:关于广告过滤和自动代理切换转载自品略图书馆 http www pinlue com article 2020 04 0206 031010213243 htmlprivoxy 广告过滤和自动代理切换最初用 Privoxy 是因为七星庐的文章强大的代理调度器代理 Privoxy 用作代理切换 后来顺便也用起它广告过滤的功能 能实现这两个功能的软件 插件很多 而且用起来往往比 privoxy 来的方便 比如 foxpro

    2025年6月8日
    6
  • Mac idea2022.01激活码【2021最新】

    (Mac idea2022.01激活码)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月31日
    318

发表回复

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

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