CopyOnWriteArrayList
COW:写时复刻——来优化子进程的使用效率
维基百科
写入时复制(英语:Copy-on-write,简称COW)是一种计算机程序设计领域的优化策略。其核心思想是,如果有多个调用者(callers)同时请求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本(private copy)给该调用者,而其他调用者所见到的最初的资源仍然保持不变。这过程对其他的调用者都是透明的(transparently)。此作法主要的优点是如果调用者没有修改该资源,就不会有副本(private copy)被建立,因此多个调用者只是读取操作时可以共享同一份资源。
Linux、Redis、文件系统都有用到
线程安全的Vector和SynchronizedList
- Vector是线程安全的容器。几乎每个方法声明处都加了synchronized关键字来使容器安全
- Collections.synchronizedList(new ArrayList())来使ArrayList变成是线程安全的话,也几乎每个方法都加上synchronized关键字,只不过它不是加在方法的生命处,而是方法的内部
基本结构
1 | final transient Object lock = new Object(); |
看起来很简单,ConpyOnWriterArrayList底层就是数组,加锁就交给ReentrantLock来完成
常用方法的实现
如果遍历Vercotr/SynchronizedList是需要自己手动加锁的
CopyOnWriterArrayList使用迭代器遍历时不需要显示枷锁
add
1 | public boolean add(E e) { |
与后面版本可能有变化
我们可以知道:再添加的时候就上锁,并复制一个新数组,增加操作在新数组上完成,最后解锁
写加锁,读不加锁
总结
再用迭代器遍历时,操作的是原数组
缺点
- 内存占用:如果CopyOnWriterArrayList经常要增删改里面的数据,比较耗费内存
- CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性
CopyOnWriteArraySet的原理就是CopyOnWriteArrayList。