使用 Guava,我想要一个具有以下属性的 map :
- 大量读取,但很少写入。
- 数据不会过期。
- 必须同步,因此一次写入是“原子的”,多次读取不会相互干扰。
- map 应该使用
MapConstraint
API,其中一些MapConstraint
是针对 map 本身的内容(通常如果记录或其他存在,则不要覆盖它:抛出一个IllegalStateException
代替)。我看到MapConstraint
接口(interface)没有对Map
进行约束。 MapConstraint
的检查必须在同步部分完成。
我已经考虑过使用 ReadWriteLock
,但我想知道 MapMaker
是否可以帮助我,因为我不太熟悉该 API。
那么我的选择是什么?
编辑:我的目标不是简单的 putIfAbsent
:我需要在插入值之前对映射执行多次检查,始终在同步写入中。
最佳答案
我不确定您是否可以使用 MapConstraint 语义轻松地做到这一点。您可以让 MapConstraint 知道底层 map ,方法是在构造期间将其传递给 map 的引用:
MapConstraints.constrainedMap(map, new MyCustomMapConstraint(map));
但这会很丑陋/有风险。有人可能会错误地做:
MapConstraint constraint = new MyCustomMapConstraint(firstMap);
Map constrainedMap = MapConstraints.constrainedMap(secondMap, constraint);
另外,它不会解决同步问题。
如果我要这样做,我会使用 ConcurrentMap 提供的“putIfAbsent”方法。我将使用 ForwardingConcurrentMap 创建一个 ConcurrentMap 包装器:
public class ProtectionistMap<K, V> extends ForwardingConcurrentMap<K, V> {
private final ConcurrentMap<K, V> delegate;
public ProtectionistMap(ConcurrentMap<K, V> delegate) {
this.delegate = checkNotNull(delegate);
}
@Override
protected ConcurrentMap<K, V> delegate() {
return delegate;
}
@Override
public V put(K key, V value) {
V result = putIfAbsent(key, value);
// The second part of the test is necessary when a map may contain null values...
if (result != null || value == null && containsKey(key)) {
throw new IllegalArgumentException("Map already had an entry for key " + key);
}
return result;
}
@Override
public void putAll(Map<? extends K, ? extends V> map) {
standardPutAll(map);
}
}
关于java - 在以某种方式同步的 map 上使用 Guava 的 MapConstraint,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4922521/