CopyOnWriteArrayList使用记录

2019-12-15  本文已影响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);

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

上一篇下一篇

猜你喜欢

热点阅读