Java实现cache的原理

package com.whpu.utils;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CacheUtil {

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    class Cache {
        private Object data;//缓存数据
        private long timeout;//超时时长
        private long creatTime;//缓存设置初始时间
    }

    private static Map<String, Cache> cacheMap = new ConcurrentHashMap<>();

    /**
     * 存入缓存
     *
     * @param key
     * @param cache
     */
    private static void put(String key, Cache cache) {
        cacheMap.put(key, cache);
    }

    /**
     * 存入缓存
     *
     * @param key
     * @param data
     * @param timeout
     */
    public static void put(String key, Object data, long timeout) {
        timeout = timeout > 0 ? timeout : 0L;
        put(key, new CacheUtil().new Cache(data, timeout, System.currentTimeMillis()));
    }

    /**
     * 根据键获取cache值
     *
     * @param key
     * @return
     */
    public static Object getCacheByKey(String key) {
        if (isExist(key) && !isTimeOut(key)) {
            return cacheMap.get(key).getData();
        }
        return null;
    }

    /**
     * 获取所有的cache
     *
     * @return
     */
    public static Map<String, Cache> getCacheAll() {
        Map<String, Cache> map = new ConcurrentHashMap<>();
        for (String key : getKeys()) {
            if (!isTimeOut(key)) {
                map.put(key, cacheMap.get(key));
            }
        }
        return map;
    }

    /**
     * 判断是否存在指定的键
     *
     * @param key
     * @return
     */
    private static boolean isExist(String key) {
        return cacheMap.containsKey(key);
    }

    /**
     * 清除所有的cache
     */
    public static void clearAll() {
        cacheMap.clear();
    }

    /**
     * 移除指定的cache
     *
     * @param key
     */
    public static void clearByKey(String key) {
        cacheMap.remove(key);
    }

    /**
     * 判断是否超时
     *
     * @param key
     * @return
     */
    public static boolean isTimeOut(String key) {
        if (!isExist(key)) {
            return true;
        }
        Cache cache = cacheMap.get(key);
        long timeout = cache.getTimeout();
        long creatTime = cache.getCreatTime();
        if (timeout == 0 || (creatTime + timeout > System.currentTimeMillis())) {
            return false;
        }
        cacheMap.remove(key);
        return true;
    }

    /**
     * 获取所有的键
     *
     * @return
     */
    public static Set<String> getKeys() {
        return cacheMap.keySet();
    }
}

测试时效性代码:

@Test
public void test() throws InterruptedException {
    CacheUtil.put("三个三","333",4000);
    System.out.println(CacheUtil.getCacheByKey("三个三"));
    Thread.sleep(2000);
    System.out.println(CacheUtil.getCacheByKey("三个三"));
    Thread.sleep(3000);
    System.out.println(CacheUtil.getCacheByKey("三个三"));
}

结果:

333
333
null

测试获取所有的cache值

@Test
public void test2() throws InterruptedException {
    CacheUtil.put("三个三","333",4000);
    CacheUtil.put("三个五","555",10000);
    CacheUtil.put("三个六","666",0);
    System.out.println(CacheUtil.getCacheAll());
    Thread.sleep(5000);
    System.out.println(CacheUtil.getCacheAll());
    Thread.sleep(6000);
    System.out.println(CacheUtil.getCacheAll());
    CacheUtil.clearByKey("三个六");
    System.out.println(CacheUtil.getCacheAll());
    CacheUtil.put("三个三","333",4000);
    CacheUtil.put("三个五","555",10000);
    CacheUtil.put("三个六","666",0);
    CacheUtil.clearAll();
    System.out.println(CacheUtil.getCacheAll());
}

结果:

{三个六=CacheUtil.Cache(data=666, timeout=0, creatTime=1594976466157), 三个三=CacheUtil.Cache(data=333, timeout=4000, creatTime=1594976466157), 三个五=CacheUtil.Cache(data=555, timeout=10000, creatTime=1594976466157)}
{三个六=CacheUtil.Cache(data=666, timeout=0, creatTime=1594976466157), 三个五=CacheUtil.Cache(data=555, timeout=10000, creatTime=1594976466157)}
{三个六=CacheUtil.Cache(data=666, timeout=0, creatTime=1594976466157)}
{}
{}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值