[英]ConcurrentModificationException - checkForComodification(ArrayList.java)
For the Below java program with Hash Map, ConcurrentModification Exception thrown, i had marked the lines where the Exception is thrown in the Program. 对于下面的带有哈希映射的Java程序,抛出ConcurrentModification Exception,我已在程序中标记了抛出Exception的行。
I had skipped the login of Insertion of Data into the HashMap for now 我现在已经跳过了将数据插入到HashMap中的登录
import java.util.ArrayList;
import java.util.HashMap;
public class MainClass {
public static void main(String[] args) {
ArrayList<HashMap<String, ArrayList<String>>> arrMain = new ArrayList<HashMap<String, ArrayList<String>>>();
HashMap<String, ArrayList<String>> hm = new HashMap<String, ArrayList<String>>();
ArrayList<String> strings = new ArrayList<String>();
// Code to build the above Maps with all required Data, Skipped for Now
//******************Scenario 1****************
for (HashMap<String, ArrayList<String>> dataMap : arrMain) { //ConcurrentModification Exception
for (String s : dataMap.get("Key")) {
ArrayList<String> newStrings = new ArrayList<String>();
newStrings.addAll(dataMap.get("Key"));
newStrings.add("New String");
dataMap.put("Key", newStrings);
}
}
//******************Scenario 2****************
for (HashMap<String, ArrayList<String>> dataMap : arrMain) {//ConcurrentModification Exception
for (String s : dataMap.get("Key")) {
dataMap.get("Key").add("New String");
}
}
}
}
Error : 错误:
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
at java.util.ArrayList$Itr.next(ArrayList.java:791)
When ever you try to modify the Collection while iterate you will get ConcurrentModificationException
. 每当您尝试在迭代时修改Collection时,都会收到
ConcurrentModificationException
。 You can try with Iterator
to avoid this. 您可以尝试使用
Iterator
来避免这种情况。
Eg: Iterator
with Map
例如:带
Map
Iterator
Map<String, String> map = new HashMap<>();
map.put("a", "a1");
map.put("b", "b1");
map.put("c", "c1");
System.out.println(map);
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry) it.next();
System.out.println(pairs.getKey() + " = " + pairs.getValue());
it.remove(); // no a ConcurrentModificationException
}
System.out.println(map);
Out put: 输出:
{b=b1, c=c1, a=a1}
b = b1
c = c1
a = a1
{}
You have marked 2 ConcurrentModificationException
points in your code but only one is reproducible and reasonable. 您在代码中标记了2个
ConcurrentModificationException
点,但是只有一个是可重现和合理的。
The 2nd one: 第二个:
for (HashMap<String, ArrayList<String>> dataMap : arrMain) {
for (String s : dataMap.get("Key")) { // HERE
dataMap.get("Key").add("New String");
}
}
dataMap.get("Key")
returns an ArrayList
to which inside the for
loop you add another element: dataMap.get("Key")
返回一个ArrayList
,在for
循环内您可以添加另一个元素:
dataMap.get("Key").add("New String");
And right after adding an element (modifying it) the for
loop would continue. 在添加元素(对其进行修改)之后,
for
循环将继续。 You add an element to the list right in the middle of iterating over it. 您可以在对其进行迭代的中间,将元素添加到列表中。 This causes the
ConcurrentModificationException
(under the hood the enhanced for
uses the iterator of the list to go over its elements, and the iterators next()
method throws this exception if the list is modified since the creation of the iterator). 这将导致
ConcurrentModificationException
(在for
的增强下for
使用列表的迭代器遍历其元素,如果自创建迭代器以来对列表进行了修改,则迭代器的next()
方法将抛出此异常)。
The 1st point in your code where you indicated ConcurrentModificationException
, it causes no exception because you iterate over a list and you modify another list, a new list which you create inside the for
loop. 在代码中指示
ConcurrentModificationException
的第一点,它不会引起异常,因为您遍历了一个列表并修改了另一个列表,这是在for
循环内创建的新列表。 But I doubt this is what you really want to do. 但是我怀疑这是您真正想要做的。
You can use ConcurrentHashMap 您可以使用ConcurrentHashMap
A hash table supporting full concurrency of retrievals and adjustable expected concurrency for updates.
哈希表支持检索的完全并发性和可更新的可调整预期并发性。
This class obeys the same functional specification as Hashtable, and includes versions of methods corresponding to each method of Hashtable.
此类遵循与Hashtable相同的功能规范,并且包括与Hashtable的每个方法相对应的方法的版本。
However, even though all operations are thread-safe, retrieval operations do not entail locking, and there is not any support for locking the entire table in a way that prevents all access.
但是,即使所有操作都是线程安全的,检索操作也不需要进行锁定,并且不支持以阻止所有访问的方式锁定整个表。
This class is fully interoperable with Hashtable in programs that rely on its thread safety but not on its synchronization details.
在依赖于其线程安全性但不依赖于其同步详细信息的程序中,此类可与Hashtable完全互操作。
You can use iterator. 您可以使用迭代器。 iterators are designed to be used by only one thread at a time.
迭代器设计为一次只能由一个线程使用。 They do not throw ConcurrentModificationException.
他们不抛出ConcurrentModificationException。
ConcurrentModificationException ConcurrentModificationException
public class ConcurrentModificationException
extends RuntimeException
This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
当不允许对对象进行同时修改时,检测到该对象的同时修改的方法可能会引发此异常。
For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it.
例如,通常不允许一个线程修改Collection而另一个线程对其进行迭代。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.