(); 一种方法通过调用 put(K,V) 将 K-V 对放入其中。 另一种方法想要从它的值中提取一组随机元素: -6ren">
gpt4 book ai didi

java - 如何在并发线程中操作 "ConcurrentModificationException"和 `values()` 时避免 HashMap `put()`?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:17:22 26 4
gpt4 key购买 nike

代码:

我有一个哈希表

private Map<K, V> map = new HashMap<>();

一种方法通过调用 put(K,V) 将 K-V 对放入其中。

另一种方法想要从它的值中提取一组随机元素:

int size = map.size();    // size > 0
V[] value_array = map.values().toArray(new V[size]);
Random rand = new Random();
int start = rand.nextInt(size); int end = rand.nextInt(size);
// return value_array[start .. end - 1]

这两个方法在两个不同的并发线程中被调用。


错误:

我遇到了一个 ConcurrentModificationException 错误:

at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
at java.util.HashMap$ValueIterator.next(Unknown Source)
at java.util.AbstractCollection.toArray(Unknown Source)

似乎一个线程中的 toArray() 方法实际上是在 HashMap 上迭代,并且在另一个线程中发生了 put() 修改。

Question: How to avoid "ConcurrentModificationException" while using HashMap.values().toArray() and HashMap.put() in concurrent threads?
Directly avoiding using values().toArray() in the second method is also OK.

最佳答案

您需要提供某种程度的同步,以便调用 puttoArray 时被阻止调用正在执行,反之亦然。有 三个 两个简单的方法:

  1. 将您的电话转接至 puttoArraysynchronized在同一个锁对象(可能是 map 本身或其他对象)上同步的 block 。
  2. 使用 Collections.synchronizedMap() 将您的 map 变成同步 map

    private Map<K, V> map = Collections.synchronizedMap(new HashMap<>());

    <罢工>

  3. 使用 ConcurrentHashMap 而不是 HashMap .

编辑:使用 Collections.synchronizedMap 的问题是一旦调用 values()返回,并发保护将消失。那时,调用 put()toArray()可能并发执行。 ConcurrentHashMap有点类似的问题,不过还是可以用的。来自 ConcurrentHashMap.values() 的文档:

The view's iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.

关于java - 如何在并发线程中操作 "ConcurrentModificationException"和 `values()` 时避免 HashMap `put()`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26621907/

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