文档章节

CopyOnWriteArraylist解析

令飞
 令飞
发布于 2015/04/18 22:53
字数 851
阅读 143
收藏 0

    自从JDK1.5引入引入concurrentHashmap,CopyOnWriteArraylist等并发集合后,java集合体系得到了很大的完善,我们有多了不少特殊情境的选择。     

    我们都知道,ArrayList存数数据的结构为数组,获取数据是根据数组下标,因此获取数据速度很快,而插入(中间)数据,删除数据却需要copy数组,因此速度较慢,而相比之下, CopyOnWriteArraylist底层的存储依然是数组,但是基本操作却不大一样。


好处(使用场景):

 Copy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略。从JDK1.5开始Java并发包里提供了两个使用CopyOnWrite机制实现的并发容器,它们是CopyOnWriteArrayList和CopyOnWriteArraySet。CopyOnWrite容器非常有用,可以在非常多的并发场景中使用到。

CopyOnWriteArrayList通过修改时拷贝原数组,而获取数组时返回老数组(相当于快照),使得修改和查看(遍历)的线程操作的是不同数组,达到避免并发修改的问题

 

缺点(不宜使用):

     1.内存占用问题

     因为CopyOnWrite的写时复制机制,所以在进行写操作的时候,内存里会同时驻扎两个对象的内存,旧的对象和新写入的对象(注意:在复制的时候只是复制容器里的引用,只是在写的时候会创建新对象添加到新容器里,而旧容器的对象还在使用,所以有两份对象内存)。如果这些对象占用的内存比较大,比如说200M左右,那么再写入100M数据进去,内存就会占用300M,那么这个时候很有可能造成频繁的Yong GC和Full GC。之前我们系统中使用了一个服务由于每晚使用CopyOnWrite机制更新大对象,造成了每晚15秒的Full GC,应用响应时间也随之变长。

  针对内存占用问题,可以通过压缩容器中的元素的方法来减少大对象的内存消耗,比如,如果元素全是10进制的数字,可以考虑把它压缩成36进制或64进制。或者不使用CopyOnWrite容器,而使用其他的并发容器,如ConcurrentHashMap

 2.数据一致性问题

CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性。所以如果你希望写入的的数据,马上能读到,请不要使用CopyOnWrite容器。

        3.性能。

    每次写都要复制的操作自然造成操作性能的下降。

代码:

 添加

 

/**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#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();
        }
    }

 

通过Arrays的copyOf方式复制数组,同时,写的操作是需要并发控制的,采用了显示锁

写的操作直接对新的数组执行


 

获取数组

  final Object[] getArray() {
        return array;
    }

 


 

© 著作权归作者所有

共有 人打赏支持
令飞
粉丝 46
博文 21
码字总数 14127
作品 0
杭州
程序员
私信 提问
CopyOnWriteArrayList与Collections.synchronizedMap性能

平台: AMD X2 5400+,2G RAM,JDK6,eclipse 3.4 CopyOnWriteArrayList:专为多线程并发设计的容器,“写入时复制”策略。 Collections.synchronizedMap:同步容器,独占策略。 分析: 可以...

MarkCo
2016/04/20
35
0
(转)线程安全的CopyOnWriteArrayList介绍

转载自:线程安全的CopyOnWriteArrayList介绍 证明CopyOnWriteArrayList是线程安全的 先写一段代码证明CopyOnWriteArrayList确实是线程安全的。 运行上面的代码,没有报出 java.util.Concurre...

晴天哥
04/24
0
0
CopyOnWriteArrayList你都不知道,怎么拿offer?

只有光头才能变强 前一阵子写过一篇COW(Copy On Write)文章,结果阅读量很低啊...COW奶牛!Copy On Write机制了解一下 可能大家对这个技术比较陌生吧,但这项技术是挺多应用场景的。除了上文...

Java3y
11/07
0
0
ArrayList源码解析之fail-fast机制深入理解

概要 前面,我们已经学习了ArrayList。接下来,我们以ArrayList为例,对Iterator的fail-fast机制进行了解。 1 fail-fast简介 fail-fast 机制是java集合(Collection)中的一种错误机制。 当多个...

sihailoveyan
05/09
0
0
并发编程6:CopyOnWriteArrayList 的写时复制

首先提个问题: 线程安全的 List 集合有什么? CopyOnWriteArrayList 的特点以及使用场景? 如果这个问题你答不上来,那这篇文章可能就对你有些价值。 读完本文你将了解: CopyOnWriteArray...

u011240877
2017/08/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

PHP生成CSV之内部换行

当我们使用PHP将采集到的文件内容保存到csv文件时,往往需要将采集内容进行二次过滤处理才能得到需要的内容。比如网页中的换行符,空格符等等。 对于空格等处理起来都比较简单,这里我们单独...

豆花饭烧土豆
31分钟前
1
0
使用 mjml 生成 thymeleaf 邮件框架模板

发邮件算是系统开发的一个基本需求了,不过搞邮件模板实在是件恶心事,估计搞过的同仁都有体会。 得支持多种客户端 支持响应式 疼彻心扉的 outlook 多数客户端只支持 inline 形式的 css 布局...

郁也风
34分钟前
4
0
让哲学照亮我们的人生——读《医务工作者需要学点哲学》有感2600字

让哲学照亮我们的人生——读《医务工作者需要学点哲学》有感2600字: 作者:孙冬梅;以前读韩国前总统朴槿惠的著作《绝望锻炼了我》时,里面有一句话令我印象深刻,她说“在我最困难的时期,...

原创小博客
今天
3
0
JAVA-四元数类

public class Quaternion { private final double x0, x1, x2, x3; // 四元数构造函数 public Quaternion(double x0, double x1, double x2, double x3) { this.x0 = ......

Pulsar-V
今天
17
0
Xshell利用Xftp传输文件,使用pure-ftpd搭建ftp服务

Xftp传输文件 如果已经通过Xshell登录到服务器,此时可以使用快捷键ctrl+alt+f 打开Xftp并展示Xshell当前的目录,之后直接拖拽传输文件即可。 pure-ftpd搭建ftp服务 pure-ftpd要比vsftp简单,...

野雪球
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部