多级缓存实现类,时间有限,该类未抽取接口,目前只支持两级缓存:JVM缓存(实现 请查看上一篇:java 手写JVM高性能缓存)、redis缓存(在spring 的 redisTemplate 基础实现)
package com.ws.commons.cache; import java.util.function.Supplier; import com.ws.commons.tool.ThreadTool; /** * 多级缓存实现 * * @author 尘无尘 * */ public class MultilevelCache { private MultilevelCache() { } private static final ICache FIRST_LEVE_LCACHE = LocalCache.instance(); private static ICache secondCache; private static final String LOCK_PREFIX = "MUILCACHE_LOCK:"; public static synchronized void init(ICache secondCache) { if (MultilevelCache.secondCache == null) { MultilevelCache.secondCache = secondCache; } } public static void put(String key, Object value, int timeOutSecond) { FIRST_LEVE_LCACHE.put(key, value, timeOutSecond); if (secondCache != null) { secondCache.put(key, value, timeOutSecond); } } /** * 提供数据,并缓存 * * @param key * @param supplier * @return */ @SuppressWarnings("unchecked") public static <T> T getForload(String key, Supplier<T> supplier) { T data = FIRST_LEVE_LCACHE.get(key); if (data == null && secondCache != null) { data = (T) secondCache.get(key); } if (data != null) { return data; } synchronized (ThreadTool.buildLock(LOCK_PREFIX, key)) { data = FIRST_LEVE_LCACHE.get(key); if (data == null && secondCache != null) { data = (T) secondCache.get(key); } if (data != null) { return data; } data = supplier.get(); if (secondCache != null) { secondCache.put(key, data); } FIRST_LEVE_LCACHE.put(key, data); } return data; } /** * 提供数据,并缓存一定的时间 * * @param key * @param timeOutSecond * @param supplier * @return */ @SuppressWarnings("unchecked") public static <T> T getForload(String key, int timeOutSecond, Supplier<T> supplier) { T data = FIRST_LEVE_LCACHE.get(key); if (data == null && secondCache != null) { data = (T) secondCache.get(key); } if (data != null) { return data; } synchronized (ThreadTool.buildLock(LOCK_PREFIX, key)) { data = FIRST_LEVE_LCACHE.get(key); if (data == null && secondCache != null) { data = (T) secondCache.get(key); } if (data != null) { return data; } data = supplier.get(); if (secondCache != null) { secondCache.put(key, data, timeOutSecond); } FIRST_LEVE_LCACHE.put(key, data, timeOutSecond); } return data; } @SuppressWarnings("unchecked") public static <T> T removeAndGet(String key) { T data = null; if (secondCache != null) { data = (T) secondCache.removeAndGet(key); } T data2 = FIRST_LEVE_LCACHE.removeAndGet(key); if (data == null) { data = data2; } return data; } public static void remove(String key) { if (secondCache != null) { secondCache.remove(key); } FIRST_LEVE_LCACHE.remove(key); } @SuppressWarnings("unchecked") public static <T> T get(String key) { T data = FIRST_LEVE_LCACHE.get(key); if (data == null && secondCache != null) { data = (T) secondCache.get(key); } return data; } public static void expire(String key, int timeOutSecond) { FIRST_LEVE_LCACHE.expire(key, timeOutSecond); if (secondCache != null) { secondCache.expire(key, timeOutSecond); } } }
redis缓存实现类
package com.walmart.cirular.interfaces.application; import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import com.ws.commons.cache.ICache; /** * redis 缓存实现类 * * @author 尘无尘 * */ @Component public class RedisICacheImpl implements ICache { @Autowired(required = false) private RedisTemplate<String, Object> redisTemplate; @Override public void put(String key, Object value) { redisTemplate.opsForValue().set(key, value); } @Override public void put(String key, Object value, int timeOutSecond) { redisTemplate.opsForValue().set(key, value, (long) timeOutSecond, TimeUnit.SECONDS); } @SuppressWarnings("unchecked") @Override public <T> T get(String key) { T t = (T) redisTemplate.opsForValue().get(key); redisTemplate.delete(key); return t; } @Override public void remove(String key) { redisTemplate.delete(key); } @SuppressWarnings("unchecked") @Override public <T> T removeAndGet(String key) { Object obj = get(key); redisTemplate.delete(key); return (T) obj; } @Override public void rightPush(String key, Object value, int timeOutSecond) { redisTemplate.opsForList().rightPush(key, value); redisTemplate.expire(key, timeOutSecond, TimeUnit.SECONDS); } @SuppressWarnings("unchecked") @Override public <T> T rightPop(String key) { return (T) redisTemplate.opsForList().rightPop(key); } @SuppressWarnings("unchecked") @Override public <T> T leftPop(String key) { return (T) redisTemplate.opsForList().leftPop(key); } @Override public void leftPush(String key, Object value) { redisTemplate.opsForList().leftPush(key, value); } @Override public void rightPush(String key, Object value) { redisTemplate.opsForList().rightPush(key, value); } @Override public void expire(String key, int timeOutSecond) { redisTemplate.expire(key, timeOutSecond, TimeUnit.SECONDS); } @Override public boolean hasKey(String key) { return redisTemplate.hasKey(key); } @Override public boolean putIfAbsent(String key, Object value) { return redisTemplate.opsForValue().setIfAbsent(key, value); } @Override public boolean putIfAbsent(String key, Object value, int timeOutSecond) { boolean flag = putIfAbsent(key, value); if (flag) { expire(key, timeOutSecond); } return flag; } }