标签:concurrentmodificati copyonwritearraylist
1
2
3
4
5
6
7
|
List<string> myList =
new ArrayList<string>(); myList.add(
"1" ); myList.add(
"2" ); myList.add(
"3" ); myList.add(
"4" ); myList.add(
"5" );</string></string> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
Iterator<string> it = myList.iterator(); while
(it.hasNext()) { String value = it.next(); if
(value.equals( "3" )) { myList.remove(value);
// error } } for
(Iterator<string> it = myList.iterator(); it.hasNext();) { String value = it.next(); if
(value.equals( "3" )) { myList.remove(value);
// error } } for
(String value : myList) { System. out.println(
"List Value:" + value); if
(value.equals( "3" )) { myList.remove(value);
// error } } </string></string> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
public
class ArrayList<e> extends
AbstractList<e> implements
Cloneable, Serializable, RandomAccess { @Override
public boolean
remove(Object object) { Object[] a = array; int
s = size; if
(object != null ) { for
( int
i = 0 ; i < s; i++) { if
(object.equals(a[i])) { System.arraycopy(a, i +
1 , a, i, --s - i); a[s] =
null ; // Prevent memory leak size = s; modCount++;
// 只要删除成功都是累加 return
true ; } } }
else { for
( int
i = 0 ; i < s; i++) { if
(a[i] == null ) { System.arraycopy(a, i +
1 , a, i, --s - i); a[s] =
null ; // Prevent memory leak size = s; modCount++;
// 只要删除成功都是累加 return
true ; } } } return
false ; }
@Override
public Iterator<e> iterator() { return
new ArrayListIterator(); }
private
class ArrayListIterator
implements Iterator<e> { ...... // 全局修改总数保存到当前类中 /** The expected modCount value */ private
int expectedModCount = modCount; @SuppressWarnings ( "unchecked" )
public E next() { ArrayList<e> ourList = ArrayList. this ; int
rem = remaining; // 如果创建时的值不相同,抛出异常 if
(ourList.modCount != expectedModCount) { throw
new ConcurrentModificationException(); } if
(rem == 0 ) { throw
new NoSuchElementException(); } remaining = rem -
1 ; return
(E) ourList.array[removalIndex = ourList.size - rem]; }
...... } } </e></e></e></e></e> |
Iterator是工作在一个独立的线程中,并且拥有一个mutex锁,就是说Iterator在工作的时候,是不允许被迭代的对象被改变的。Iterator被创建的时候,建立了一个内存索引表(单链表),这个索引表指向原来的对象,当原来的对象数量改变的时候,这个索引表的内容没有同步改变,所以当索引指针往下移动的时候,便找不到要迭代的对象,于是产生错误。List、Set等是动态的,可变对象数量的数据结构,但是Iterator则是单向不可变,只能顺序读取,不能逆序操作的数据结构,当Iterator指向的原始数据发生变化时,Iterator自己就迷失了方向。
List、Set、Map 都可以通过Iterator进行遍历,这里仅仅是通过List举例,在使用其他集合遍历时进行增删操作都需要留意是否会触发ConcurrentModificationException异常。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
// 1 使用Iterator提供的remove方法,用于删除当前元素 for
(Iterator<string> it = myList.iterator(); it.hasNext();) { String value = it.next(); if
(value.equals( "3" )) { it.remove();
// ok } } System. out.println(
"List Value:" + myList.toString()); // 2 建一个集合,记录需要删除的元素,之后统一删除
List<string> templist =
new ArrayList<string>(); for
(String value : myList) { if
(value.equals( "3" )) { templist.remove(value); } } // 可以查看removeAll源码,其中使用Iterator进行遍历 myList.removeAll(templist); System. out.println(
"List Value:" + myList.toString());
// 3. 使用线程安全CopyOnWriteArrayList进行删除操作 List<string> myList =
new CopyOnWriteArrayList<string>(); myList.add(
"1" ); myList.add(
"2" ); myList.add(
"3" ); myList.add(
"4" ); myList.add(
"5" ); Iterator<string> it = myList.iterator(); while
(it.hasNext()) { String value = it.next(); if
(value.equals( "3" )) { myList.remove(
"4" ); myList.add(
"6" ); myList.add(
"7" ); } } System. out.println(
"List Value:" + myList.toString()); // 4. 不使用Iterator进行遍历,需要注意的是自己保证索引正常 for
( int
i = 0 ; i < myList.size(); i++) { String value = myList.get(i); System. out.println(
"List Value:" + value); if
(value.equals( "3" )) { myList.remove(value);
// ok i--;
// 因为位置发生改变,所以必须修改i的位置 } } System. out.println(
"List Value:" + myList.toString());</string></string></string></string></string></string> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
final
List<string> myList = createTestData(); new
Thread( new Runnable() { @Override public
void run() { for
(String string : myList) { System.out.println( "遍历集合 value = "
+ string); try
{ Thread.sleep( 100 ); }
catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); new
Thread( new Runnable() { @Override public
void run() { for
(Iterator<string> it = myList.iterator(); it.hasNext();) { String value = it.next(); System.out.println( "删除元素 value = "
+ value); if
(value.equals( "3" )) { it.remove(); } try
{ Thread.sleep( 100 ); }
catch (InterruptedException e) { e.printStackTrace(); } } } }).start();</string></string> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
List<string> myList =
new CopyOnWriteArrayList<string>(); myList.add(
"1" ); myList.add(
"2" ); myList.add(
"3" ); myList.add(
"4" ); myList.add(
"5" ); new
Thread( new Runnable() { @Override public
void run() { for
(String string : myList) { System.out.println( "遍历集合 value = "
+ string); try
{ Thread.sleep( 100 ); }
catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); new
Thread( new Runnable() { @Override public
void run() { for
( int
i = 0 ; i < myList.size(); i++) { String value = myList.get(i); System.out.println( "删除元素 value = "
+ value); if
(value.equals( "3" )) { myList.remove(value); i--;
// 注意 } try
{ Thread.sleep( 100 ); }
catch (InterruptedException e) { e.printStackTrace(); } } } }).start();</string></string> |
ArrayList引起的ConcurrentModificationException 异常原因及解决方法
标签:concurrentmodificati copyonwritearraylist
原文地址:http://blog.csdn.net/lhl6688/article/details/43968265