缓存接口-方法定义
public interface BizCache {
void set(String key, String value);
void set(String key, String value, long timeout);
String get(String key);
boolean containsKey(String key);
default void pruneCache() {
}
}
缓存配置类-超时配置
public class BizCacheConfig {
public static long timeout = 3 * 60 * 1000;
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;
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;
public class BizDefaultCache implements BizCache {
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);
}
}
@Override
public void set(String key, String value) {
set(key, value, BizCacheConfig.timeout);
}
@Override
public void set(String key, String value, long timeout) {
writeLock.lock();
try {
stateCache.put(key, new CacheState(value, timeout));
} finally {
writeLock.unlock();
}
}
@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();
}
}
@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();
}
}
}
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管理
@AutoConfiguration
public class BizCacheAutoConfiguration {
@Bean
public BizStateCache bizDefaultCache() {
return new BizDefaultCache();
}
}