zoukankan      html  css  js  c++  java
  • ConcurrentModificationException 问题

    原文地址: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对象,并不是实时.

     

     

     

  • 相关阅读:
    行列式学习笔记
    二项式反演学习笔记
    【AtCoder】ARC096(C
    【LOJ】#2127. 「HAOI2015」按位或
    [ACM] POJ 1218 THE DRUNK JAILER (关灯问题)
    lua的弱弱引用表
    西班牙式软件团队
    【DRP】採用dom4j完毕XML文件导入数据库
    基于Linux平台病毒Wirenet.c解析
    【剑指offer】异或去重
  • 原文地址:https://www.cnblogs.com/sunwufan/p/2511747.html
Copyright © 2011-2022 走看看