多线程环境中的ConcurrentModificationException
在多线程环境中,如果在检测资源的过程中,任何方法发现存在不允许的并发修改,则可能会抛出ConcurrentModificationException。
- 如果检测到此异常,则迭代的结果是不确定的。
- 通常,一些迭代器实现选择在遇到此异常时立即抛出,称为fail-fast iterators 。
例如:如果我们尝试使用线程修改代码中的任何集合,但另一个线程已经在使用该集合,那么这是不允许的。
单线程环境中的ConcurrentModificationException
由于无法保证每当引发此异常时,对象都会被某个不同的线程并发修改,因此在单线程环境中也会引发此异常。
如果我们在一个对象上调用一系列违反其约定的方法,那么该对象将抛出 ConcurrentModificationException。
例如:如果在迭代集合时,我们直接尝试修改该集合,则给定的fail-fast 迭代器将抛出此 ConcurrentModificationException。
例子:在以下代码中,实现了ArrayList。然后在遍历时添加很少的值并且对其进行很少的修改,
// Java program to show
// ConcurrentModificationException
import java.util.Iterator;
import java.util.ArrayList;
public class modificationError {
public static void main(String args[])
{
// Creating an object of ArrayList Object
ArrayList<String> arr
= new ArrayList<String>();
arr.add("One");
arr.add("Two");
arr.add("Three");
arr.add("Four");
try {
// Printing the elements
System.out.println(
"ArrayList: ");
Iterator<String> iter
= arr.iterator();
while (iter.hasNext()) {
System.out.print(iter.next()
+ ", ");
// ConcurrentModificationException
// is raised here as an element
// is added during the iteration
System.out.println(
"\n\nTrying to add"
+ " an element in "
+ "between iteration\n");
arr.add("Five");
}
}
catch (Exception e) {
System.out.println(e);
}
}
}
输出:
ArrayList: One, Trying to add an element in between iteration java.util.ConcurrentModificationException
如何避免ConcurrentModificationException?
为了避免这种异常,
- 简单地,我们可以在迭代完成后进行修改,或者
- 实施synchronized block or method的概念
例子:我们来看看如何通过简单改变修改的地方来解决这个异常。
// Java program to show
// ConcurrentModificationException
import java.util.Iterator;
import java.util.ArrayList;
public class modificationError {
public static void main(String args[])
{
// Creating an object of ArrayList Object
ArrayList<String> arr
= new ArrayList<String>();
arr.add("One");
arr.add("Two");
arr.add("Three");
arr.add("Four");
try {
// Printing the elements
System.out.println(
"ArrayList: ");
Iterator<String> iter
= arr.iterator();
while (iter.hasNext()) {
System.out.print(iter.next()
+ ", ");
}
// No exception is raised as
// a modification is done
// after the iteration
System.out.println(
"\n\nTrying to add"
+ " an element in "
+ "between iteration: "
+ arr.add("Five"));
// Printing the elements
System.out.println(
"\nUpdated ArrayList: ");
iter = arr.iterator();
while (iter.hasNext()) {
System.out.print(iter.next()
+ ", ");
}
}
catch (Exception e) {
System.out.println(e);
}
}
}
输出:
ArrayList: One, Two, Three, Four, Trying to add an element in between iteration: true Updated ArrayList: One, Two, Three, Four, Five,
从输出中可以清楚地看到,只需对代码进行最小的更改,就可以消除ConcurrentModificationException。
相关用法
- Java ConcurrentMap用法及代码示例
- Java ConcurrentHashMap computeIfPresent()用法及代码示例
- Java ConcurrentHashMap equals()用法及代码示例
- Java ConcurrentHashMap forEach()用法及代码示例
- Java ConcurrentHashMap getOrDefault()用法及代码示例
- Java ConcurrentHashMap hashcode()用法及代码示例
- Java ConcurrentHashMap mappingCount()用法及代码示例
- Java ConcurrentHashMap merge()用法及代码示例
- Java ConcurrentHashMap newKeySet()用法及代码示例
- Java ConcurrentHashMap replace()用法及代码示例
- Java ConcurrentHashMap toString()用法及代码示例
- Java ConcurrentLinkedQueue forEach()用法及代码示例
- Java ConcurrentLinkedQueue removeAll()用法及代码示例
- Java ConcurrentLinkedQueue removeIf()用法及代码示例
- Java ConcurrentLinkedQueue retainAll()用法及代码示例
- Java ConcurrentHashMap contains()用法及代码示例
- Java ConcurrentHashMap containsKey()用法及代码示例
- Java ConcurrentHashMap containsValue()用法及代码示例
- Java ConcurrentHashMap elements()用法及代码示例
- Java ConcurrentHashMap entrySet()用法及代码示例
- Java ConcurrentHashMap get()用法及代码示例
- Java ConcurrentHashMap isEmpty()用法及代码示例
- Java ConcurrentHashMap keys()用法及代码示例
- Java ConcurrentHashMap keySet()用法及代码示例
- Java ConcurrentHashMap put()用法及代码示例
注:本文由纯净天空筛选整理自sanskar_bindal大神的英文原创作品 ConcurrentModificationException in Java with Examples。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。