1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| 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 { 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); } expireTimeMap.put(key, nowTime); return cacheValue; } finally { writeLock.unlock(); } } }
|