import com.weds.framework.core.exception.ErrorCodeException;
import lombok.Data;
import lombok.SneakyThrows;
import org.apache.commons.lang3.ObjectUtils;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* @description: <br/>
* 基于ConcurrentHashMap封装的缓存工具类
* <p>
* <br/>
* @author: Qz1997
* @create 2021/7/9 11:00
*/
@SuppressWarnings("unused")
public class MapCacheManager {
/**
* 私有构造单例模式
*/
private MapCacheManager() {
}
/**
* 是否开启清除失效缓存
*/
private volatile Boolean clearExpireCacheEnable = true;
/**
* 缓存失效时间 30分钟
*/
private long cacheTimeout = 30 * 60 * 1000L;
/**
* 可缓存最大数量
*/
private Integer maxCacheSize = 200;
/**
* 重入读写锁
*/
private static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
/**
* 读锁
*/
private static Lock writeLock = reentrantReadWriteLock.writeLock();
/**
* 写锁
*/
private static Lock readLock = reentrantReadWriteLock.readLock();
/**
* 存储对象的ConcurrentHashMap
*/
private final static Map<String, CacheEntry> CACHE_ENTRY_MAP = new ConcurrentHashMap<>();
/**
* 初始化
*/
public void init() {
initClearTask();
}
/**
* 初始化 自定义缓存失效时间
*
* @param cacheTimes 缓存失效时间
*/
public void init(long cacheTimes) {
this.cacheTimeout = cacheTimes;
initClearTask();
}
/**
* 初始化 自定义缓存失效时间
*
* @param cacheTimes 缓存失效时间
* @param maxCacheSize 最大缓存数
*/
public void init(long cacheTimes, int maxCacheSize) {
this.cacheTimeout = cacheTimes;
this.maxCacheSize = maxCacheSize;
initClearTask();
}
/**
* 清除缓存线程
*/
private void initClearTask() {
//启动清除失效缓存数据
if (clearExpireCacheEnable) {
new ClearCacheTask().start();
}
}
/**
* 获取缓存管理器
*
* @return 缓存管理器
*/
public static MapCacheManager getCacheManagerInstance() {
return CacheManagerFactory.CACHE_MANAGER;
}
/**
* 获取缓存管理器工厂
*
* @author Qz1997
*/
private static class CacheManagerFactory {
private static final MapCacheManager CACHE_MANAGER = new MapCacheManager();
}
/**
* 清除缓存工具
*
* @author Qz1997
*/
private class ClearCacheTask extends Thread {
ClearCacheTask() {
super.setName("清除缓存线程");
}
@Override
@SneakyThrows
public void run() {
while (clearExpireCacheEnable) {
CACHE_ENTRY_MAP.keySet().forEach(key -> {
writeLock.lock();
try {
CacheEntry entry = CACHE_ENTRY_MAP.get(key);
long now = System.currentTimeMillis();
if (ObjectUtils.isNotEmpty(entry) && entry.lastTouchTime < now) {
CACHE_ENTRY_MAP.remove(key);
}
} finally {
writeLock.unlock();
}
});
Thread.sleep(1000);
}
}
}
/**
* 缓存对象
*
* @author Qz1997
*/
@Data
private static class CacheEntry {
long lastTouchTime;
Object value;
CacheEntry(Object value, long lastTouchTime) {
super();
this.value = value;
this.lastTouchTime = lastTouchTime + System.currentTimeMillis();
}
}
/**
* 获取缓存的value
*
* @param key 缓存Key
* @return value
*/
public Object get(String key) {
CacheEntry entry;
readLock.lock();
try {
entry = CACHE_ENTRY_MAP.get(key);
} finally {
readLock.unlock();
}
if (null == entry) {
return null;
}
return entry.value;
}
/**
* 获取缓存的value
*
* @param key 缓存Key
* @return value
*/
@SuppressWarnings("unchecked")
public <T> T get(String key, Class<T> clazz) {
if (ObjectUtils.isEmpty(clazz)) {
return null;
}
CacheEntry entry;
readLock.lock();
try {
entry = CACHE_ENTRY_MAP.get(key);
} finally {
readLock.unlock();
}
if (null == entry) {
return null;
}
return (T) entry.value;
}
/**
* 向缓存中加值
*
* @param key 缓存中的Key
* @param value 缓存中的value
*/
public void put(String key, Object value) {
put(key, value, 0);
}
/**
* 向缓存中加值
*
* @param key 缓存中的Key
* @param value 缓存中的value
* @param lastTouchTime 缓存过期时间
*/
public void put(String key, Object value, long lastTouchTime) {
if (CACHE_ENTRY_MAP.size() > maxCacheSize) {
throw new ErrorCodeException("缓存大小超出限制");
}
// 过期时间
lastTouchTime = lastTouchTime <= 0 ? cacheTimeout : (lastTouchTime * 1000);
CacheEntry entry = new CacheEntry(value, lastTouchTime);
writeLock.lock();
try {
CACHE_ENTRY_MAP.put(key, entry);
} finally {
writeLock.unlock();
}
}
/**
* 删除
*
* @param key 缓存中的Key
*/
public void delete(String key) {
if (null == key) {
return;
}
writeLock.lock();
try {
CACHE_ENTRY_MAP.remove(key);
} finally {
writeLock.unlock();
}
}
/**
* 情况缓存
*/
public void clear() {
writeLock.lock();
try {
CACHE_ENTRY_MAP.clear();
} finally {
writeLock.unlock();
}
}
}
基于ConcurrentHashMap封装的缓存工具类
最新推荐文章于 2024-06-21 14:29:27 发布