Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 174194e

Browse filesBrowse files
authored
Merge pull request giantray#72 from AcceptedBoy/master
【add】iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re.md
2 parents 8fffae4 + 8561923 commit 174194e
Copy full SHA for 174194e

File tree

Expand file treeCollapse file tree

1 file changed

+69
-0
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+69
-0
lines changed
+69Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
## 遍历集合时移除元素,怎样避免ConcurrentModificationException异常抛出
2+
3+
#### 问题:
4+
5+
在遍历集合的过程中,不会总出现`ConcurrentModificationException`异常的抛出,但是在下面的代码块中:
6+
7+
```java
8+
public static void main(String[] args) {
9+
Collection<Integer> l = new ArrayList<Integer>();
10+
11+
for (int i=0; i < 10; ++i) {
12+
l.add(new Integer(4));
13+
l.add(new Integer(5));
14+
l.add(new Integer(6));
15+
}
16+
17+
//遍历的过程中移除部分集合元素
18+
for (Integer i : l) {
19+
if (i.intValue() == 5) {
20+
l.remove(i);
21+
}
22+
}
23+
24+
System.out.println(l);
25+
}
26+
```
27+
28+
运行之后,结果显而易见,总是会抛出异常:
29+
30+
```java
31+
Exception in thread "main" java.util.ConcurrentModificationException
32+
```
33+
34+
所以,遍历集合时移除元素,怎样避免ConcurrentModificationException异常的产生?有什么好的解决办法?
35+
36+
#### 回答:
37+
38+
`Iterator.remove()`是线程安全的,所以你的代码可以这样写:
39+
40+
```java
41+
List<String> list = new ArrayList<>();
42+
43+
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
44+
String string = iterator.next();
45+
if (string.isEmpty()) {
46+
47+
// 从迭代器中移除集合元素,集合中相应的集合元素也会安全地被移除
48+
// 在这里,如果继续调用的是list.remove(string),那么仍会抛出异常
49+
iterator.remove();
50+
}
51+
}
52+
```
53+
54+
在遍历集合时修改集合的结构或内容的情况中,`Iterator.remove()`是唯一线程安全的方法。
55+
56+
#### 问题原因:
57+
58+
fail-fast, 快速失败机制,是java集合类的一种错误检查机制。当有多个线程同时对集合进行遍历以及内容或者结构的修改时,就有可能产生fail-fast机制。这意味着,当它们发现容器在迭代的过程中被修改时,就会抛出一个ConcurrentModificationException异常。
59+
60+
迭代器的快速失败行为无法得到保证,它不能保证一定会出现该错误,但是快速失败操作会尽最大努力抛出ConcurrentModificationException异常,这个异常仅用于检测bug。这种迭代器并不是完备的处理机制,而只是作为并发问题的一个预警指示器。
61+
62+
63+
#### 拓展阅读:
64+
65+
[fail-fast机制的原理解析](https://github.com/AcceptedBoy/backstage-vacation-plan/blob/master/chapter1/concurrency/fail-fast.md)
66+
67+
#### StackOverFlow地址:
68+
69+
[http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re](http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.