packagecom.ws.commons.cache;importjava.util.function.Supplier;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importcom.ws.commons.tool.ThreadTool;/*** 多级缓存实现
*
*@author尘无尘
**/
public classMultilevelCache {private static final Logger LOGGER = LoggerFactory.getLogger(MultilevelCache.class);privateMultilevelCache() {
}private static final ICache FIRST_LEVE_LCACHE =LocalCache.instance();private staticICache secondCache;private static final String LOCK_PREFIX = "MUILCACHE_LOCK:";public static synchronized voidinit(ICache secondCache) {if (MultilevelCache.secondCache == null) {
MultilevelCache.secondCache=secondCache;
LOGGER.info("开启二级缓存,secondCache:{}", secondCache);
}
}public static void put(String key, Object value, inttimeOutSecond) {if (secondCache != null) {
secondCache.put(key, value, timeOutSecond);
FIRST_LEVE_LCACHE.put(key, value, cmpFirstCacheTimeOutSecond(timeOutSecond));
}else{
FIRST_LEVE_LCACHE.put(key, value, timeOutSecond);
}
}/*** 提供数据,并缓存
*
*@paramkey
*@paramsupplier
*@return
*/
public static T computeIfAbsent(String key, Suppliersupplier) {
T data=FIRST_LEVE_LCACHE.get(key);if (data == null && secondCache != null) {
data=secondCache.get(key);
}if (data != null) {returndata;
}synchronized(ThreadTool.buildLock(LOCK_PREFIX, key)) {
data=FIRST_LEVE_LCACHE.get(key);if (data == null && secondCache != null) {
data=secondCache.get(key);
}if (data != null) {returndata;
}
data=supplier.get();if (secondCache != null) {
secondCache.put(key, data);
FIRST_LEVE_LCACHE.put(key, data,60);
}else{
FIRST_LEVE_LCACHE.put(key, data);
}
}returndata;
}/*** 提供数据,并缓存一定的时间
*
*@paramkey
*@paramtimeOutSecond
*@paramsupplier
*@return
*/
public static T computeIfAbsent(String key, int timeOutSecond, Suppliersupplier) {
T data=FIRST_LEVE_LCACHE.get(key);if (data == null && secondCache != null) {
data=secondCache.get(key);
}if (data != null) {returndata;
}synchronized(ThreadTool.buildLock(LOCK_PREFIX, key)) {
data=FIRST_LEVE_LCACHE.get(key);if (data == null && secondCache != null) {
data=secondCache.get(key);
}if (data != null) {returndata;
}
data=supplier.get();if (secondCache != null) {
secondCache.put(key, data, timeOutSecond);
FIRST_LEVE_LCACHE.put(key, data, cmpFirstCacheTimeOutSecond(timeOutSecond));
}else{
FIRST_LEVE_LCACHE.put(key, data, timeOutSecond);
}
}returndata;
}public static T removeAndGet(String key) {
T data= null;if (secondCache != null) {
data=secondCache.removeAndGet(key);
}
T data2=FIRST_LEVE_LCACHE.removeAndGet(key);if (data == null) {
data=data2;
}returndata;
}public static voidremove(String key) {if (secondCache != null) {
secondCache.remove(key);
}
FIRST_LEVE_LCACHE.remove(key);
}public static T get(String key) {
T data=FIRST_LEVE_LCACHE.get(key);if (data == null && secondCache != null) {
data=secondCache.get(key);
}returndata;
}public static void expire(String key, inttimeOutSecond) {
FIRST_LEVE_LCACHE.expire(key, timeOutSecond);if (secondCache != null) {
secondCache.expire(key, timeOutSecond);
}
}private static int cmpFirstCacheTimeOutSecond(inttimeOutSecond) {if (timeOutSecond > 60) {return 60;
}else if (timeOutSecond > 30) {return timeOutSecond / 2;
}returntimeOutSecond;
}
}