JUC-6.2-并发容器-CopyOnWriteArrayList

了解了并发安全的 HashMap 之后,再来看看并发安全的 ArrayList ,就是 CopyOnWriteArrayList, 早期的版本中有 VectorSynchronizedList 但是这两个锁的粒度太大,所以并发效率并不高, Copy-On-Write 并发容器还包括 CopyOnWriteArraySet 用来替代同步 Set

适用场景

CopyOnWriteArrayList 适用于读操作尽可能快,写操作可以慢一点的地方,或者读取比写入多的地方

读写规则

CopyOnWriteArrayList 读取完全不需要加锁,写入也不会阻塞读取操作,只有写入和写入之间需要同步等待

设计思想

CopyOnWrite 通俗的来说,就是往容器中添加一个元素的时候,不是直接往当前容器添加,而是先将当前的容器复制一份作为一个新的容器,然后在新的容器中添加,添加完成之后,再将原容器的引用指向新的容器,所以 CopyOnWrite 容器进行并发的读的时候,不需要加锁,因为当前容器不会添加任何元素,但是这样做将不能保证数据的实时性

用一个案例来看一下,代码如下

public class ListTest {
    public static void main(String[] args) {
        CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>(new Integer[]{1, 2, 3, 4, 5});

        Iterator<Integer> iterator1 = list.iterator();
        list.add(6);
        Iterator<Integer> iterator2 = list.iterator();

        iterator1.forEachRemaining(System.out::println);
        iterator2.forEachRemaining(System.out::println);
        
    }
}

这段代码的运行结果如下

1
2
3
4
5
1
2
3
4
5
6

可以看到 iterator1 这个迭代器并没有6这元素

实现原理

看一下这个类的源码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6WawyU0Z-1587203746640)(http://r.photo.store.qq.com/psc?/V10eEnSd0rz4Am/2aGbA7qLSN6GeC6g0ZsuRUJps5qSLNP*l.RArA*NM*y7NaOKKJqnyx8Up0GFq3MM7mMuLCp*oMLrKBN9LWlpmE6Zl4hK6Vo0vjE8j6bH3yQ!/r)]

这个类里面维护的就是一个数组

然后看看 add()get() 方法

扫描二维码关注公众号,回复: 10921981 查看本文章

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F2EVrWwC-1587203746642)(http://r.photo.store.qq.com/psc?/V10eEnSd0rz4Am/2aGbA7qLSN6GeC6g0ZsuRX1uye4hkyCJ10XJ.TbpK8nY0..C7lG9ZaksK1G*gTGZ**qzhqK9jzt3iqRRpF8Ass5fWrmge*VYcUnq6XDLfMs!/r)]

首先上锁,保证只有一个线程修改,先复制,改完之后把新的再放到上面的数组中,数组引用是 volatile 修饰的,因此将旧的数组引用指向新的数组,根据 volatilehappens-before 规则,写线程对数组引用的修改对读线程是可见的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yBc70Mxt-1587203746643)(http://r.photo.store.qq.com/psc?/V10eEnSd0rz4Am/2aGbA7qLSN6GeC6g0ZsuReNSwx1B55IHigZ5y6dmIdQVxWuXa.J.qRkLU8AsdWRnI3iZPVyNWGsoT9VGVDmJg8*6MQ0Zowc.5cYQ1TJXq20!/r)]

get() 方法就很简单了,直接返回

缺点

  1. 不能保证数据一致性
  2. 内存占用,写操作的时候,内存中会有两个对象

总结

了解 CopyOnWriteArrayList 的原理,以及可能会带来的一些问题

发布了76 篇原创文章 · 获赞 1 · 访问量 5067

猜你喜欢

转载自blog.csdn.net/qq_38083545/article/details/105602416
今日推荐