遍历List出现问题:ConcurrentModificationException.md

问题

某一天增加计算的节点后发现在遍历节点List出现如下问题:

1
2
3
4
5
6
7
8
9
10
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at com.sdg.mir.sync.impl.SyncThreeDegreeDetail.exec(SyncThreeDegreeDetail.java:70)
at com.sdg.mir.sync.impl.SyncThreeDegreeDetail.main(SyncThreeDegreeDetail.java:199)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

原因

原来ArrayList只有一个元素不会出现这种问题。当增加节点后,ArrayList中的元素增加,由于ArrayList是线程不安全的。
foreach遍历arraylist是使用Iterator迭代器的。
一般是不允许一个线程在用迭代器遍历的同时,另一个线程在修改的。
后来在发现代码里在循环的最后居然清空了list,o(╯□╰)o.所以报了错。及时修正代码解决了问题
不过之前眼瞎没有看到这个时候把ArrayList换成了CopyOnWriteArrayList也是解决了问题。
CopyOnWriteArrayList创建迭代器时使用了对数组状态的引用。此数组在迭代器的生存期内不会更改,因此不可能发生冲突,
并且迭代器保证不会抛出 ConcurrentModificationException。创建迭代器以后,迭代器就不会反映列表的添加、移除或者更改。
在迭代器上进行的元素更改操作(remove、set 和 add)不受支持。这些方法将抛出 UnsupportedOperationException。