1、接口
package yourpackage;
import java.util.function.Function;
/**
* @param <K> 键类型
* @param <V> 值类型
* @author huangjinzhou
* @date 2019/8/21 19:31
*/
public interface Cache<K, V> {
/**
* 从缓存获取指定键的值,如果不存在,返回<code>supplier</code>取得的值
*
* @param key 键
* @param supplier 值提供器
* @return 值
*/
V get(K key, Function<K, V> supplier);
}
2、基于SoftReference和ConcurrentHashMap实现:
package yourpackage;
import java.lang.ref.SoftReference;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
/**
* @author huangjinzhou
* @date 2019/8/21 19:32
*/
public class InMemorySoftReferenceCache<K, V> implements Cache<K, V> {
private volatile SoftReference<Map<K, V>> cacheRef = null;
/**
* 是否有线程在临界区,true-是,false-无
*/
private final AtomicBoolean cacheLock = new AtomicBoolean(false);
@Override
public V get(K key, Function<K, V> supplier) {
SoftReference<Map<K, V>> cacheRef = this.cacheRef;
Map<K, V> cache = cacheRef == null ? null : cacheRef.get();
V value;
if (cache != null && ((value = cache.get(key)) != null || cache.containsKey(key))) {
return value;
}
if ((cacheRef = this.cacheRef) == null || (cache = cacheRef.get()) == null) {
boolean locked;
do {
// 自旋等待
locked = !cacheLock.compareAndSet(false, true);
} while (locked);
try {
if ((cacheRef = this.cacheRef) == null || (cache = cacheRef.get()) == null) {
cache = new ConcurrentHashMap<>(8);
this.cacheRef = new SoftReference<>(cache);
}
} finally {
cacheLock.set(false);
}
}
return cache.computeIfAbsent(key, supplier);
}
}