Java 通用本地缓存
·2 min read
Java 通用本地缓存
简介
| 主要还是利用好 ReentrantReadWriteLock 对读写进行锁操作
代码例子
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Supplier;
public class CacheLockTest {
static final Map<String, Integer> expireTimeMap = new HashMap<>();
static final Map<String, ReentrantReadWriteLock> readWriteLockMap = new HashMap<>();
static final Map<String, Object> readWriteCacheMap = new HashMap<>();
@Test
public void fetchCachedTest() throws Exception {
for (int ii=0; ii<20; ii++) {
Thread.sleep(1000);
System.out.println(">>>" + ii);
fetchCached("abc", 0, ()->{return new ArrayList<String>(){{add("aa"); add("bb");}};});
fetchCached("abcd", 10, ()->{return 111;});
fetchCached("abcde", 10, ()->{return "abc";});
}
}
public Object fetchCached(String key, Integer expireSecond, Supplier<Object> supplier) {
if (readWriteLockMap.get(key) == null) {
readWriteLockMap.put(key, new ReentrantReadWriteLock());
}
return fetchCached(key, expireSecond, readWriteLockMap.get(key).readLock(), readWriteLockMap.get(key).writeLock(), supplier);
}
public Object fetchCached(String key, Integer expireSecond, Lock readLock, Lock writeLock, Supplier<Object> supplier) {
// 当前时间
int nowTime = (int)(System.currentTimeMillis()/1000);
// 上次时间
Integer lastTime = expireTimeMap.get(key);
readLock.lock();
try {
// System.out.printf("%s , %s, %s, %s%n", key, nowTime, lastTime, expireSecond);
if (readWriteCacheMap.get(key)!=null && lastTime!=null && (expireSecond==0 || nowTime<expireSecond+lastTime)) {
return readWriteCacheMap.get(key);
}
}
finally {
readLock.unlock();
}
writeLock.lock();
try {
lastTime = expireTimeMap.get(key);
if (readWriteCacheMap.get(key)!=null && lastTime!=null && (expireSecond==0 || nowTime<expireSecond+lastTime)) {
return readWriteCacheMap.get(key);
}
Object cacheValue = supplier.get();
Object oldCacheValue = readWriteCacheMap.get(key);
if (oldCacheValue instanceof Map) {
((Map<?, ?>) oldCacheValue).clear();
if (cacheValue instanceof Map) {
((Map<?, ?>) oldCacheValue).putAll((Map) cacheValue);
}
else {
readWriteCacheMap.put(key, cacheValue);
}
}
else if (oldCacheValue instanceof Collection) {
((Collection<?>) oldCacheValue).clear();
if (cacheValue instanceof Collection) {
System.out.println("cacheValue > " + cacheValue);
((Collection<?>) oldCacheValue).addAll((Collection) cacheValue);
}
else {
readWriteCacheMap.put(key, cacheValue);
}
}
else {
readWriteCacheMap.put(key, cacheValue);
}
// System.out.println(readWriteCacheMap.get(key));
expireTimeMap.put(key, nowTime);
// return key
return cacheValue;
}
finally {
writeLock.unlock();
}
}
}