java - 在以某种方式同步的 map 上使用 Guava 的 MapConstraint

标签 java dictionary synchronization guava

使用 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/

相关文章:

java - 在Java中,我可以依靠引用分配是原子的来实现写时复制吗?

java - 安卓应用程序为空

java - 如何为下载管理器编写测试驱动的 Java 类?

java - 如何从 JSON 响应中获取所有属性名称(嵌套或非嵌套)

swift - 如何在给定 Swift 中的键的情况下返回映射数据的值?

go - 如何正确使用sync.Cond?

java - mysql 小数(10,2) 提取java

java - Google DataStore 无主一对多关系

python - 如何将字典中的现有 csv 文件写入特定列?

.NET:向同一应用程序的所有实例发送文本消息并阅读