美文网首页
CopyOnWriteArrayList使用记录

CopyOnWriteArrayList使用记录

作者: 土肥圆的诺诺 | 来源:发表于2019-12-15 16:30 被阅读0次

    最近在编写弹窗层级的时候,写了一个方法,就是在遍历集合,取出集合中的对象,然后网络请求,当请求回来的时候,更改集合状态,代码如下

    //遍历集合 并做异步加载
    for (IHomeDialog dialog : thisLevelDialogs) {
      //判断当前弹窗是否需要校验
        if (dialog.needToAgainCheck()) {
          //去网络加载
            dialog.loadInterface(new HomeDialogNetCallBack() {
                @Override
                public void loadError(IHomeDialog dialog) {
                  //改变thisLevelDialogs的集合状态
                  doSomethings();
                   
                }
    
                @Override
                public void loadNeedShow(IHomeDialog dialog) {
                    //改变thisLevelDialogs的集合状态
                  doSomethings();
                   
                }
    
                @Override
                public void loadNotNeed(IHomeDialog dialog) {
                    //改变thisLevelDialogs的集合状态
                  doSomethings();
    
                }
            });
        } 
    }
    

    然而...崩溃了(ConcurrentModificationException )

    转念一想,也对,ArrayList是非线性安全,此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException。即在一方在便利列表,而另一方在修改列表时,会报ConcurrentModificationException错误。而这不是唯一的并发时容易发生的错误,在多线程进行插入操作时,由于没有进行同步操作,容易丢失数据。但是加锁吧,觉得太重量级。用Vector吧,我度娘后发现,这玩意过时了。不建议使用。

    接下来,引入了Collections.synchronizedList和CopyOnWriteArrayList

    在一波查询后发现,(下面是我复制的)

    CopyOnWriteArrayList和Collections.synchronizedList是实现线程安全的列表的两种方式。两种实现方式分别针对不同情况有不同的性能表现,其中CopyOnWriteArrayList的写操作性能较差,而多线程的读操作性能较好。而Collections.synchronizedList的写操作性能比CopyOnWriteArrayList在多线程操作的情况下要好很多,而读操作因为是采用了synchronized关键字的方式,其读操作性能并不如CopyOnWriteArrayList。因此在不同的应用场景下,应该选择不同的多线程安全实现类。

    我选择了CopyOnWriteArrayList,我主要是进行读写,而且没几个数据,不怕效率低下。(而且在代码上省事)

    好吧到此问题应该解决了。

    但是我在后面做了个排序,也就是sort操作,然后java.lang.UnsupportedOperationException

    CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
    list.add("1");
    list.add("2");
    Collections.sort(list, new Comparator<String>() {
        @Override
        public int compare(String s, String t1) {
            return (s.length() - t1.length());
    
        }
    });
    

    好吧,又查询了下,CopyOnWriteArrayList不支持set,然后只能贼无奈的找个集合遍历完,然后塞进去。

    CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
    ArrayList<String> resList = new ArrayList<>();
    resList.add("1");
    resList.add("2");
    resList.add("2");
    
    
    Collections.sort(resList, new Comparator<String>() {
        @Override
        public int compare(String s, String t1) {
            return (s.length() - t1.length());
    
        }
    });
    
    list.addAll(resList);
    

    到此为止,记录下,下次再记录。

    相关文章

      网友评论

          本文标题:CopyOnWriteArrayList使用记录

          本文链接:https://www.haomeiwen.com/subject/rzaknctx.html