欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > > 文章正文

说说ArrayList的ConcurrentModificationException,

来源: javaer 分享于  点击 16308 次 点评:57

说说ArrayList的ConcurrentModificationException,


试用for-earch遍历ArrayList,调用remove方法时候,常常回报ConcurrentModificationException异常,今天来从源码上解析这个问题.

列出来问题

代码1:

     ArrayList<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("2");
        list.add("2");
        for (String e : list) {
            System.out.println(e);
            if (e.equals("1")) {
                list.remove(e);
            }
        }

output:

1
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
    at java.util.ArrayList$Itr.next(ArrayList.java:851)
    at com.own.learn.jdk.ref.Test.main(Test.java:17)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

``
**代码2:**
    ArrayList<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("2");
    list.add("2");
    for (int i=0; i< list.size(); i++) {
        String e =  list.get(i);
        System.out.println(e);
        if (e.equals("2")) {
            list.remove(e);
        }
    }
output:

1
2
2

**代码三:**
    ArrayList<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("2");
    list.add("2");
    for (Iterator<String> it = list.iterator(); it.hasNext();) {
        String next = it.next();
        if(next.equals("2"))
            it.remove();
        System.out.println(next);
    }
output:

1
2
2
2


###解决问题
1,checkForComodification报错,查看源码:
  final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
我们可以清楚看到,modCount和expectedModCount不相等的时候,才有这个问题
list自带的reomve方法调用了fastRemove是:
  private void fastRemove(int index) {
    modCount++;
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // clear to let GC do its work
}
modCount和expectedModCount方法不同步
而Itr中的remove方法:
  public void remove() {
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();

        try {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }

“`
modCount和expectedModCount方法同步
到这里ConcurrentModificationException解决了
2,代码2中输出少了一个数字,为啥呢.答案在上面的fastRemove中

相关文章

    暂无相关文章

用户点评