与Guava HashBiMap和synchronizedBiMap同步

Enw*_*red 3 java guava

我在多线程情况下从 Guava BiMap 的 putIfAbsent 方法中收到异常。我应该如何正确保护它免受线程问题的影响?

我这样创建地图:

BiMap<Integer, java.net.URI> cache = com.google.common.collect.Maps.synchronizedBiMap(HashBiMap.create());

然后,我修改地图的唯一一次是通过cache.clear();cache.putIfAbsent(a,b)

我偶尔会看到这个堆栈跟踪:

java.lang.IllegalArgumentException: value already present: http://example.com
    at com.google.common.collect.HashBiMap.put(HashBiMap.java:279)
    at com.google.common.collect.HashBiMap.put(HashBiMap.java:260)
    at java.util.Map.putIfAbsent(Map.java:744)
    at com.google.common.collect.Synchronized$SynchronizedMap.putIfAbsent(Synchronized.java:1120)
Run Code Online (Sandbox Code Playgroud)

这是 HashBiMap 或 SynchronizedBiMap 中的错误吗?或者我需要为线程安全做额外的工作吗?

使用guava-25.0-jreJava(TM) SE Runtime Environment 1.8.0_152-b16

msa*_*ord 5

因为 aBiMap提供了从值到键的映射,以及通常Map从键到值的映射,所以每个值只能与单个键配对。尝试将一个值与多个唯一键关联将导致IllegalArgumentException您看到这样的结果。

听起来您的问题与线程无关,而是与数据相关。

例如,这将引发类似的异常。问题是存在值“Bar”和两个单独的键“Foo”和“Baz”:

    public static void main(String[] args) {
        BiMap<String, String> m = HashBiMap.create();
        m.put("Foo", "Bar");
        m.put("Baz", "Bar"); // Throws IllegalArgumentException "value already present"
    }
Run Code Online (Sandbox Code Playgroud)