ConcurrentModificationException问题

来源:互联网 发布:乐贝网络校园招聘 编辑:程序博客网 时间:2024/06/10 00:44

原文地址:http://blog.csdn.net/phoenix2121/article/details/5757623

http://zhidao.baidu.com/question/271631895.html

方法一(效率不高):

这个问题是说,你不能在对一个List进行遍历的时候将其中的元素删除掉 解决办法是,你可以先将要删除的元素用另一个list装起来,等遍历结束再remove掉 可以这样写

复制代码
List delList = new ArrayList();//用来装需要删除的元素for(Information ia:list)     if(ia.getId()==k){          n++;           delList.add(ia);      } list.removeAll(delList);//遍历完成后执行删除
复制代码

 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

方法二:同步操作list时,一边迭代remove,一边新增.那么会报错 java.util.ConcurrentModificationException

 

查看api发现vector有个好方法可以解决这个错误.

 

首先是用arraylist

复制代码
//    private  Vector list;//两种list方式    private  List list;            public  void init(){//        list = new Vector();        list = new ArrayList();        list.add("a");        list.add("b");        list.add("c");        list.add("d");        list.add("e");        list.add("f");    }        public  void removeIt(){//iterator        Iterator it = list.iterator();        for(int i=0;it.hasNext();i++){            String a = (String)it.next();            System.out.println(a);            if(a.equals("c")){                //list.remove(a);                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                }                it.remove();                System.out.println("remove c");            }        }            }    //    public void removeEm(){//enumeration//        Enumeration e = list.elements();//        for(int i=0;e.hasMoreElements();i++){//            String a = (String)e.nextElement();//            System.out.println(a);//            if(a.equals("c")){//                try {//                        Thread.sleep(1000);//                } catch (InterruptedException ee) {//                }//                list.remove(a);//                System.out.println("remove c");//            }//        }//    }        public  void add(){//先用迭代,再添加        try {            Thread.sleep(500);        } catch (Exception e) {            // TODO: handle exception        }        list.add("c");        System.out.println("add c");    }                public void run() {        removeIt();//        removeEm();    }    public static void main(String[] args) {        TestConcurrentModificationException t = new TestConcurrentModificationException();        t.init();        t.start();        t.add();    }
复制代码

运行结果:

a
b
c
add c
Exception in thread "Thread-0" java.util.ConcurrentModificationException
 at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
 at java.util.AbstractList$Itr.remove(Unknown Source)
 at test.TestConcurrentModificationException.removeIt(TestConcurrentModificationException.java:33)
 at test.TestConcurrentModificationException.run(TestConcurrentModificationException.java:69)

 

 

 

其次是vector

 

复制代码
    private  Vector list;//两种list方式//    private  List list;            public  void init(){        list = new Vector();//        list = new ArrayList();        list.add("a");        list.add("b");        list.add("c");        list.add("d");        list.add("e");        list.add("f");    }        public  void removeIt(){//iterator        Iterator it = list.iterator();        for(int i=0;it.hasNext();i++){            String a = (String)it.next();            System.out.println(a);            if(a.equals("c")){                //list.remove(a);                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                }                it.remove();                System.out.println("remove c");            }        }            }        public void removeEm(){//enumeration        Enumeration e = list.elements();        for(int i=0;e.hasMoreElements();i++){            String a = (String)e.nextElement();            System.out.println(a);            if(a.equals("c")){                try {                        Thread.sleep(1000);                } catch (InterruptedException ee) {                }                list.remove(a);                System.out.println("remove c");            }        }    }        public  void add(){//先用迭代,再添加        try {            Thread.sleep(500);        } catch (Exception e) {            // TODO: handle exception        }        list.add("c");        System.out.println("add c");    }                public void run() {//        removeIt();        removeEm();    }    public static void main(String[] args) {        TestConcurrentModificationException t = new TestConcurrentModificationException();        t.init();        t.start();        t.add();    }
复制代码

运行结果:

 

a
b
c
add c
remove c
e
f
c
remove c

api上说,

由 Vector 的 iterator 和 listIterator 方法所返回的迭代器是快速失败的:如果在迭代器创建后的任意时间从结构上修改了向量(通过迭代 器自身的 remove 或 add 方法之外的任何其他方式),则迭代器将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就完全失败,而不是冒着在将来不确定的时间任意发生 不确定行为的风险。Vector 的 elements 方法返回的 Enumeration 不是 快速失败的。

注意,迭代器的快速失败行为不能得到保证,一般来说,存在不同步的并发修改时,不可能作出任何坚决的保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的程序的方式是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测 bug。

 

 

当然如果使用其他的集合,那就没有什么好办法了.只有存放起来,每次取一个list对象,并不是实时.

 

0 0
原创粉丝点击