我正在创建一个具有以下特征的记忆缓存:
- 缓存未命中将导致计算和存储条目
- 这种计算非常昂贵
- 这个计算是幂等的
- 无界(条目从未被删除),因为:
- 输入将导致最多 500 个条目
- 每个存储的条目都非常小
- 缓存的寿命相对较短(通常不到一个小时)
- 总的来说,内存使用不是问题
- 将有数千次读取 - 在缓存的生命周期内,我预计 99.9%+ 的缓存命中率
- 必须是线程安全的
什么会具有卓越的性能,或者在什么条件下一种解决方案比另一种更受青睐?
线程本地哈希映射:
class MyCache {
private static class LocalMyCache {
final Map<K,V> map = new HashMap<K,V>();
V get(K key) {
V val = map.get(key);
if (val == null) {
val = computeVal(key);
map.put(key, val);
}
return val;
}
}
private final ThreadLocal<LocalMyCache> localCaches = new ThreadLocal<LocalMyCache>() {
protected LocalMyCache initialValue() {
return new LocalMyCache();
}
};
public V get(K key) {
return localCaches.get().get(key);
}
}
并发哈希映射:
class MyCache {
private final ConcurrentHashMap<K,V> map = new ConcurrentHashMap<K,V>();
public V get(K key) {
V val = map.get(key);
if (val == null) {
val = computeVal(key);
map.put(key, val);
}
return val;
}
}
我认为如果有很多线程,因为每个线程的所有缓存未命中,ThreadLocal 解决方案最初会更慢,但是在数千次读取之后,摊销成本将低于 ConcurrentHashMap 解决方案。我的直觉正确吗?
还是有更好的解决方案?