java - 与 Guava HashBiMap 和 synchronizedBiMap 同步
问题描述
在多线程情况下,我从 Guava BiMap 的 putIfAbsent 方法中得到一个异常。我应该如何正确保护它免受线程问题的影响?
我这样创建地图:
BiMap<Integer, java.net.URI> cache = com.google.common.collect.Maps.synchronizedBiMap(HashBiMap.create());
然后,我修改地图的唯一时间是 bycache.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)
这是 HashBiMap 或 synchronizedBiMap 中的错误吗?还是我需要为线程安全做额外的工作?
使用guava-25.0-jre
和Java(TM) SE Runtime Environment 1.8.0_152-b16
解决方案
因为 aBiMap
提供了从值到键的映射,以及Map
从键到值的通常映射,所以每个值只能与单个键配对。尝试将一个值与多个唯一键相关联将导致IllegalArgumentException
您看到的结果。
听起来您的问题与线程无关,而是与数据有关。
例如,这将引发类似的异常。问题是存在带有两个单独键“Foo”和“Baz”的值“Bar”:
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"
}
推荐阅读
- firebase - 访问 Firestore 集合
- python - Selenium - 查找 h1 和 p 文本的文章
- asp.net - 如何从数据表 gridData 绑定中修复 checkmarx 存储的 XSS 问题
- xamarin - 需要在不调用 xamarin.forms 中的 Every catch 内的 save log 方法的情况下全局存储已处理的异常
- html - 格式化 HTML 丢失的驱动器
- jquery - 来自对象的数据集以创建图表
- hibernate - Hibernate:如何解决循环问题
- java - Java 抽象类方法
- java - 如何通过手动bean进行依赖注入?
- r - 突出显示整行而不是单元格