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, 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, Cache> getCacheAll() { Map, 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> getKeys() { return cacheMap.keySet(); } }

【Java实现cache的原理】测试时效性代码:
@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=https://www.it610.com/article/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)} {} {}

    推荐阅读