我想使用番石榴来制作具有以下属性的地图:


读很多,但是写很少。
数据不会过期。
必须同步,因此写入是“原子的”并且多次读取不会相互干扰。
该地图应使用MapConstraint API,其中一些MapConstraint与地图本身的内容背道而驰(通常,如果记录或其他记录存在,请勿覆盖它:改为抛出IllegalStateException)。我看到MapConstraint界面不会给Map带来约束。
MapConstraint的检查必须在同步部分内部进行。


我已经考虑过使用ReadWriteLock了,但是我想知道MapMaker是否可以在这里为我提供帮助,因为我对该API不太熟悉。

那我有什么选择呢?



编辑:我的目标不是一个简单的putIfAbsent:我需要在插入值之前对映射执行多次检查,始终在同步写入中进行。

最佳答案

我不确定您是否可以使用MapConstraint语义轻松地做到这一点。您可以通过在构造过程中向其传递对地图的引用来使MapConstraint知道底层地图:

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/

10-09 12:45