Java(自行实现)内存缓存(带过期时间)生成环境适用

缓存接口-方法定义


/**
 *  Biz缓存,用来缓存State
 *
 * @author YZD 
 */
public interface BizCache {
    
    

    /**
     * 设置缓存
     *
     * @param key   缓存KEY
     * @param value 缓存内容
     */
    void set(String key, String value);

    /**
     * 设置缓存,指定过期时间
     *
     * @param key     缓存KEY
     * @param value   缓存内容
     * @param timeout 指定缓存过期时间(毫秒)
     */
    void set(String key, String value, long timeout);

    /**
     * 获取缓存
     *
     * @param key 缓存KEY
     * @return 缓存内容
     */
    String get(String key);

    /**
     * 是否存在key,如果对应key的value值已过期,也返回false
     *
     * @param key 缓存KEY
     * @return true:存在key,并且value没过期;false:key不存在或者已过期
     */
    boolean containsKey(String key);

    /**
     * 清理过期的缓存
     */
    default void pruneCache() {
    
    
    }
}

缓存配置类-超时配置

 /**
 * BizCache配置类
 *
 * @author YZD
 */
public class BizCacheConfig {
    
    

    /**
     * 默认缓存过期时间:3分钟
     * 鉴于授权过程中,根据个人的操作习惯,或者授权平台的不同(google等),每个授权流程的耗时也有差异,不过单个授权流程一般不会太长
     * 本缓存工具默认的过期时间设置为3分钟,即程序默认认为3分钟内的授权有效,超过3分钟则默认失效,失效后删除
     */
    public static long timeout = 3 * 60 * 1000;

    /**
     * 是否开启定时{@link BizDefaultCache#pruneCache()}的任务
     */
    public static boolean schedulePrune = true;
}

缓存调度器-定时任务-守护线程


import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 缓存调度器
 *
 * @author YZD
 */
public enum BizCacheScheduler {
    
    

    /**
     * 当前实例
     */
    INSTANCE;

    private  final AtomicInteger cacheTaskNumber = new AtomicInteger(1);
    private ScheduledExecutorService scheduler;

    BizCacheScheduler() {
    
    
        create();
    }

    private void create() {
    
    
        this.shutdown();
        this.scheduler = new ScheduledThreadPoolExecutor(10, r -> new Thread(r, String.format("BizCache-Task-%s", cacheTaskNumber.getAndIncrement())));
    }

    public void shutdown() {
    
    
        if (null != scheduler) {
    
    
            this.scheduler.shutdown();
        }
    }

    public void schedule(Runnable task, long delay) {
    
    
        this.scheduler.scheduleAtFixedRate(task, delay, delay, TimeUnit.MILLISECONDS);
    }
}

默认缓存实现

 
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 默认的缓存实现
 *
 * @author YZD
 */
public class BizDefaultCache implements BizCache {
    
    

    /**
     *   cache map
     */
    private static  final Map<String, CacheState> stateCache = new ConcurrentHashMap<>();
    private final ReentrantReadWriteLock cacheLock = new ReentrantReadWriteLock(true);
    private final Lock writeLock = cacheLock.writeLock();
    private final Lock readLock = cacheLock.readLock();

    public BizDefaultCache() {
    
    
        if (BizCacheConfig.schedulePrune) {
    
    
            this.schedulePrune(BizCacheConfig.timeout);
        }
    }

    /**
     * 设置缓存
     *
     * @param key   缓存KEY
     * @param value 缓存内容
     */
    @Override
    public void set(String key, String value) {
    
    
        set(key, value, BizCacheConfig.timeout);
    }

    /**
     * 设置缓存
     *
     * @param key     缓存KEY
     * @param value   缓存内容
     * @param timeout 指定缓存过期时间(毫秒)
     */
    @Override
    public void set(String key, String value, long timeout) {
    
    
        writeLock.lock();
        try {
    
    
            stateCache.put(key, new CacheState(value, timeout));
        } finally {
    
    
            writeLock.unlock();
        }
    }

    /**
     * 获取缓存
     *
     * @param key 缓存KEY
     * @return 缓存内容
     */
    @Override
    public String get(String key) {
    
    
        readLock.lock();
        try {
    
    
            CacheState cacheState = stateCache.get(key);
            if (null == cacheState || cacheState.isExpired()) {
    
    
                return null;
            }
            return cacheState.getState();
        } finally {
    
    
            readLock.unlock();
        }
    }

    /**
     * 是否存在key,如果对应key的value值已过期,也返回false
     *
     * @param key 缓存KEY
     * @return true:存在key,并且value没过期;false:key不存在或者已过期
     */
    @Override
    public boolean containsKey(String key) {
    
    
        readLock.lock();
        try {
    
    
            CacheState cacheState = stateCache.get(key);
            return null != cacheState && !cacheState.isExpired();
        } finally {
    
    
            readLock.unlock();
        }
    }

    /**
     * 清理过期的缓存
     */
    @Override
    public void pruneCache() {
    
    
        Iterator<CacheState> values = stateCache.values().iterator();
        CacheState cacheState;
        while (values.hasNext()) {
    
    
            cacheState = values.next();
            if (cacheState.isExpired()) {
    
    
                values.remove();
            }
        }
    }

    /**
     * 定时清理
     *
     * @param delay 间隔时长,单位毫秒
     */
    public void schedulePrune(long delay) {
    
    
        BizCacheScheduler.INSTANCE.schedule(this::pruneCache, delay);
    }

    @Getter
    @Setter
    private  static class CacheState implements Serializable {
    
    
        private String state;
        private long expire;

        CacheState(String state, long expire) {
    
    
            this.state = state;
            // 实际过期时间等于当前时间加上有效期
            this.expire = System.currentTimeMillis() + expire;
        }

        boolean isExpired() {
    
    
            return System.currentTimeMillis() > this.expire;
        }
    }
}

自定义缓存实现-略

交由Spring管理

/**
 *  
 * @author YZD
 */
@AutoConfiguration 
public class BizCacheAutoConfiguration {
    
    

    @Bean
    public BizStateCache bizDefaultCache() {
    
    
        return new BizDefaultCache();
    }

}

猜你喜欢

转载自blog.csdn.net/qq_35385687/article/details/143229820