0


CopyOnWriteArrayList可同时读写操作线性安全的集合(含底层实现)

本篇介绍一个知识点-CopyOnWriteArrayList

它是一个线性安全的集合,可同时进行读写修改的List

  • 举两个例子:
fun formatModels(data : MutableList<GetTemplateResp.DataDTO>?) : MutableList<GetTemplateResp.DataDTO>?{
        if(data != null && data.size > 0){
            var tempList = CopyOnWriteArrayList(data)
            for(item in tempList){
                if(item.userDeviceTemplateInfoVoList == null || item.userDeviceTemplateInfoVoList.size > chooseDeviceList!!.size){
                    tempList.remove(item)
                }
            }
            return tempList
        }else{
            return null
        }
    }

这里的tempList 我在便利的同时一边在删除数据,其它集合做不到。再看另一个例子

private static CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
    @SneakyThrows
    public static void main(String[] args) {
        // 创建新增元素线程
        Thread thread1 = new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                for (int i = 0; i < 8; i++) {
                    list.add("element-" + i);
                    log.info("添加元素 element-{}", i);
                    Thread.sleep(100);
                }
            }
        });
        // 创建删除元素线程
        Thread thread2 = new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    if(list.size() > 0){
                        list.remove(0);
                        log.info("删除元素----- element-{}", i);
                    }
                    Thread.sleep(200);
                }
            }
        });
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        log.info("list中的最终元素:{}", list);
        // 遍历元素
        for (String element: list){
            log.info("打印元素:{}", element);
        }
    }

运行结果如下:
23:03:24.187 [Thread-0] - 添加元素 element-0
23:03:24.187 [Thread-1] - 删除元素----- element-0
23:03:24.296 [Thread-0] - 添加元素 element-1
23:03:24.397 [Thread-1] - 删除元素----- element-1
23:03:24.397 [Thread-0] - 添加元素 element-2
23:03:24.498 [Thread-0] - 添加元素 element-3
23:03:24.600 [Thread-1] - 删除元素----- element-2
23:03:24.600 [Thread-0] - 添加元素 element-4
23:03:24.703 [Thread-0] - 添加元素 element-5
23:03:24.805 [Thread-1] - 删除元素----- element-3
23:03:24.807 [Thread-0] - 添加元素 element-6
23:03:24.909 [Thread-0] - 添加元素 element-7
23:03:25.007 [Thread-1] - 删除元素----- element-4
23:03:25.211 [main] - list中的最终元素:[element-5, element-6, element-7]
23:03:25.212 [main] - 打印元素:element-5
23:03:25.212 [main] - 打印元素:element-6
23:03:25.212 [main] - 打印元素:element-7

这里简单说一下它的原理吧,先看一组图:

在这里插入图片描述
比如你正在使用它进行add()添加元素,它实际上是把原数据copy(复制)了一份出来,在新的数组里面进行操作;同样的你在进行remove的时候或者update的时候也是同理,它实际上不是直接操作的原数据源,而是拷贝出来操作,这样就不会出现索引越界或者同时读取边删除的错误了,这也是为什么说它是线性安全的原因了。

看两个源码:
在这里插入图片描述
在这里插入图片描述
对于没用过这个东西或者初学者来说,结合我对它的介绍和源码,一目了然,它始终操作的新拷贝的数据,然后把新整理好的数据返回给外层,在公司项目开发中难免会有这种情况,用这个很方便。

这里补充一点,普通ArrayList如何直接转换成CopyOnWriteArrayList,如果项目中已经用的是普通的ArrayList,不用重新写,如下:
Kotlin:
var arry = arrayListOf()
var copyList = CopyOnWriteArrayList(arry)

Java:
List aList = new ArrayList<>();
aList.add(“1”);
aList.add(“2”);
aList.add(“3”);
aList.add(“4”);
CopyOnWriteArrayList copyList = new CopyOnWriteArrayList(aList.toArray());

或者
List aList = new ArrayList<>();
aList.add(“1”);
aList.add(“2”);
aList.add(“3”);
aList.add(“4”);
CopyOnWriteArrayList copyList = new CopyOnWriteArrayList(aList);

这里说一下大概的使用场景吧,可能不全,说个大概吧,自己根据自己实际情况使用:
1.例如要操作并发处理的时候(比如消息并发)
2.多个线程同时访问一个数据源的时候
3.项目不大,可以不需要自己去封装一套消息队列的时候,可以用它来处理。
4.集合中需要进行比较和剔除
总之,同时读取和删除、更新的时候可以用它。

本篇完。

标签: 安全 java android

本文转载自: https://blog.csdn.net/qq_31070753/article/details/142564180
版权归原作者 没有笔的小新是路飞。 所有, 如有侵权,请联系我们删除。

“CopyOnWriteArrayList可同时读写操作线性安全的集合(含底层实现)”的评论:

还没有评论