package william
.pattern
;
import java
.util
.HashMap
;
import java
.util
.Map
;
import java
.util
.concurrent
.ConcurrentHashMap
;
import java
.util
.concurrent
.locks
.Lock
;
import java
.util
.concurrent
.locks
.ReadWriteLock
;
import java
.util
.concurrent
.locks
.ReentrantReadWriteLock
;
import java
.util
.function
.Supplier
;
public class SimpleCache<K, V> {
private Map
<K, V> cache
= new HashMap<>();
private Map
<K, ReadWriteLock> locks
= new ConcurrentHashMap<>();
public V
get(K key
, Supplier
<V> optionsWhenMiss
) {
V value
;
try {
acquireLock(key
, false);
value
= cache
.get(key
);
} finally {
releaseLock(key
, false);
}
if (value
!= null
) {
return value
;
}
try {
acquireLock(key
, true);
value
= cache
.get(key
);
if (value
== null
) {
value
= optionsWhenMiss
.get();
}
} finally {
releaseLock(key
, true);
}
return value
;
}
public void put(K key
, V value
) {
try {
acquireLock(key
, true);
cache
.put(key
, value
);
} finally {
releaseLock(key
, true);
}
}
private void acquireLock(K key
, boolean write
) {
Lock lock
= lockForKey(key
, write
);
lock
.lock();
}
private void releaseLock(K key
, boolean write
) {
Lock lock
= lockForKey(key
, write
);
lock
.unlock();
}
private Lock
lockForKey(K key
, boolean write
) {
ReadWriteLock rw
= locks
.computeIfAbsent(key
, k
-> new ReentrantReadWriteLock());
return write
? rw
.writeLock() : rw
.readLock();
}
}
转载请注明原文地址: https://yun.8miu.com/read-18290.html