发布时间:2020-04-18 19:30:31来源:阅读:
写入时复制(CopyOnWrite,简称COW)思想是计算机程序设计领域中的一种通用优化策略。其核心思想是,如果有多个调用者(Callers)同时访问相同的资源(如内存或者是磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者修改资源内容时,系统才会真正复制一份专用副本(private copy)给该调用者,而其他调用者所见到的最初的资源仍然保持不变。这过程对其他的调用者都是透明的(transparently)。此做法主要的优点是如果调用者没有修改资源,就不会有副本(private copy)被创建,因此多个调用者只是读取操作时可以共享同一份资源。
通俗易懂的讲,写入时复制技术就是不同进程在访问同一资源的时候,只有更新操作,才会去复制一份新的数据并更新替换,否则都是访问同一个资源。
JDK 的 CopyOnWriteArrayList 容器正是采用了 COW 思想,它是如何工作的呢?简单来说,就是平时查询的时候,都不需要加锁,随便访问,只有在更新的时候,才会从原来的数据复制一个副本出来,然后修改这个副本,最后把原数据替换成当前的副本。修改操作的同时,读操作不会被阻塞,而是继续读取旧的数据。这点要跟读写锁区分一下。
我们先来看看 CopyOnWriteArrayList 的 add() 方法,其实也非常简单,就是在访问的时候加锁,拷贝出来一个副本,先操作这个副本,再把现有的数据替换为这个副本。
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
CopyOnWriteArrayList 的 get(int index) 方法就是普通的无锁访问。
public E get(int index) {
return get(getArray(), index);
}
@SuppressWarnings("unchecked")
private E get(Object[] a, int index) {
return (E) a[index];
}
对于一些读多写少的数据,写入时复制的做法就很不错,例如配置、黑名单、物流地址等变化非常少的数据,这是一种无锁的实现。可以帮我们实现程序更高的并发。
CopyOnWriteArrayList 并发安全且性能比 Vector 好。Vector 是增删改查方法都加了synchronized 来保证同步,但是每个方法执行的时候都要去获得锁,性能就会大大下降,而 CopyOnWriteArrayList 只是在增删改上加锁,但是读不加锁,在读方面的性能就好于 Vector。
数据一致性问题。这种实现只是保证数据的最终一致性,在添加到拷贝数据而还没进行替换的时候,读到的仍然是旧数据。
内存占用问题。如果对象比较大,频繁地进行替换会消耗内存,从而引发 Java 的 GC 问题,这个时候,我们应该考虑其他的容器,例如 ConcurrentHashMap。
上一篇:如何加装3G上网卡
Fastcopy (文件急速复制工具) v3.61.0.0
1.64 MB
奇奇剪贴复制工具下载
2.69M
51彩虹(即时聊天软件) 2.3.0.1 最新版
11.8M
NewFileTime(文件时间修改软件) v3.99 中文版
186KB
即时通下载
1.12MB
咪咪桌面时钟下载
2.72MB
嘟嘟语音(即时通信软件) v3.2.282.0 免费版
73.2M
定时关机3000 v10.0.8 免费版
7.12M
定时提醒软件下载
2.2M
小译同传(语音实时翻译软件) 2020 破解版
38.75MB
效能时间管理下载
15.5MB
数字时钟(桌面时钟工具) v2.3.0 绿色版
22KB
欢乐吧多人视频聊天(即时聊天工具) v5.971 免费版
14MB
爱建证券 (实时证劵交易软件)v6.69 官方版
74.8M
电脑报时下载
1.97 MB
网易POPO(多媒体即时通讯工具) V8.0.1.163 绿色版
12.78 MB
betterwmf下载
2.7M
儿童上网下载
4.6M
多文本剪贴板
49.94 KB
2020-02-21
E47指纹软件如何安装及录入指纹?
KVM+Qemu+Libvirt实战
Lenovo笔记本常见光驱厚度
联想智能电视与其它有线电视、数字电视有什么区别?
光盘的日常保养
如何禁用指纹的开机提示
最古老的 npm 包 request 已弃用,每周下载量达 1400 万+
k8s的flannel安装报错Failed to create SubnetManager: error retrieving pod spec解决
在WIN10上使用cmd窗口命令编译Android OpenCV