gpt4 book ai didi

java - map 中的并发修改问题

转载 作者:行者123 更新时间:2023-12-04 05:33:00 25 4
gpt4 key购买 nike

我正在使用 并发哈希映射 结构的

Map<Set<Date>, Map<String, Object>> SampleMap

给定映射( Map<String, Object> )中使用的映射也是并发散列映射,
但 set 是唯一的 TreeSet类型。

当我在日志中添加以下行时,我仍然收到并发修改异常,
logger.debug("sampleMap.keySet() + ". Size is " + sampleMap.keySet().size()"); 

以及处理这张 map 的同一类的其他一些部分。

此映射被多个线程广泛用于批处理过程中,以在映射中放置和删除值,所使用的 Java 版本为 1.5。

我认为异常是由于 Treeset 造成的,而且我发现类型 Set 没有类似的并发处理集合的实现。

如果有人确认我对给定问题的思考是否正确,并请提出解决此问题的建议,那就太好了?

最佳答案

由于您需要能够“修改” key ,因此您需要遵循此模式

// lock the collection
Map<String, Object> values = map.remove(key);
key = new TreeSet<String>(key);
// modify copy of key
map.put(key, values);
// unlock the collection.

当您执行 ConcurrentMap 不支持的操作时,您必须使用自己的锁定。您可以使用带有同步或 ReentrantReadWriteLock 的普通 HashMap 或 LinkedHashMap。

您可以使用创建并发集
// Added in Java 1.6
Set<String> set = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
// or to be sorted
Set<String> set = Collections.newSetFromMap(new ConcurrentSkipListMap<String, Boolean>());

但是,您无法更改 key 的内容,因此您应该使用的是
Set<String> key = Collections.unmodifiableSet(treeSet);
// or to be sure its not modified
Set<String> key = Collections.unmodifiableSet(new TreeSet<String>(treeSet));

一个简单的例子,说明为什么在 Map 中使用后不能更改键。
Set<String> key1 = new TreeSet<String>();
Map<Set<String>, Boolean> map = new ConcurrentHashMap<Set<String>, Boolean>();
map.put(key1, true);
System.out.println("Is the map ok? "+map.containsKey(key1));
key1.add("hello");
System.out.println("Is the map ok? "+map.containsKey(key1));

版画
Is the map ok? true
Is the map ok? false

常见的行为是它无法再看到 map 中的键。这是因为映射根据其哈希码将键放入桶中。如果 hashCode 改变,它可能在错误的存储桶中,所以当它寻找它时,它找不到它。

关于java - map 中的并发修改问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12350735/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com