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

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


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)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • 【论文笔记】Unmasking DeepFakes with simple Features「建议收藏」

    【论文笔记】Unmasking DeepFakes with simple Features「建议收藏」@MENGM0本文使用图像的功率谱特征实现了对高分率伪造人脸图片的检测。Introduction文章2019年11月发布在arxiv上,提出了使用图像的功率谱(PowerSpectrum)作为特征,使用简单的机器学习方法(SVM)进行伪造图像的取证。作者的Github。数据集作者制作了一个名为Faces-HQ的数据集,19GB,真实图片来自CelebA-HQ和Flickr-Faces-…

    2022年5月22日
  • UDP flood攻击_udp攻击是什么意思

    UDP flood攻击_udp攻击是什么意思UDPFlood是日渐猖厥的流量型DoS攻击,原理也很简单。常见的情况是利用大量UDP小包冲击DNS服务器或Radius认证服务器、流媒体视频服务器。100kpps的UDPFlood经常将线路上的骨干设备例如防火墙打瘫,造成整个网段的瘫痪。由于UDP协议是一种无连接的服务,在UDPFLOOD攻击中,攻击者可发送大量伪造源IP地址的小UDP包。但是,由于UDP协议是无连接性的,所以只要开了一个UDP的端口提供相关服务的话,那么就可针对相关的服务进行攻击。…

    2022年9月26日
  • 特立独行的理解_幸福在一起第14集

    特立独行的理解_幸福在一起第14集原题链接对一个十进制数的各位数字做一次平方和,称作一次迭代。如果一个十进制数能通过若干次迭代得到 1,就称该数为幸福数。1 是一个幸福数。此外,例如 19 经过 1 次迭代得到 82,2 次迭代后得到 68,3 次迭代后得到 100,最后得到 1。则 19 就是幸福数。显然,在一个幸福数迭代到 1 的过程中经过的数字都是幸福数,它们的幸福是依附于初始数字的。例如 82、68、100 的幸福是依附于 19 的。而一个特立独行的幸福数,是在一个有限的区间内不依附于任何其它数字的;其独立性就是依附于它的的幸福数

    2022年8月8日
  • safari每次打开都是上次未关闭页面_页码一直不变怎么改

    safari每次打开都是上次未关闭页面_页码一直不变怎么改bootstrapTable刷新当前页码不变和从第一页开始查询

    2022年4月20日
  • 微商分销功能不能用了

    微商分销功能不能用了“三级以上分销将会被停止支付功能和封停账号”,日前一则“不利”消息彻底引爆微商的主要阵地——微信朋友圈。一时间关于分销三级变二级、微商寒冬将至的说法再次疯传。自央视曝光部分微商涉嫌传销之后,微信今年接连对微商们“动刀”,强化管理意在行业正规化发展,失去多级分销之后,依靠内容深度揽客的方式成为微商转型的方向。微商连遭重创刚刚过去的一周,微商们再次体验到了人生的跌宕起伏。认证为腾讯微信

    2022年5月13日
  • Java定时器(Timer)「建议收藏」

    Java定时器(Timer)「建议收藏」1.介绍Timer和TimerTask是用于在后台线程中调度任务的javautil类。简单地说,TimerTask是要执行的任务,Timer是调度器。2.调度一次性任务2.1指定延迟后执行让我们从简单地在定时器的帮助下运行单个任务开始:@TestpublicvoidgivenUsingTimer_whenSchedulingTaskOnce_thenCorrect(){TimerTasktask=newTimerTask(){publicvoid

    2022年7月7日

发表回复

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

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