概要

JDK中提供ArrayList集合方便我们对集合内元素进行增删改查,但是ArrayList为了能够在单线程中快速进行操作其设计并不支持多线程进行操作。ArrayList在多线程环境下可能会产生java.util.ConcurrentModificationException异常。而对于我们需要在多线程下操作集合Jdk为我们内置了支持多线程操作的并发集合类供我们使用。

Vector

Vector始于JDK1.0版本而ArrayList始于JDK1.2版本。Vector对于每个对集合操作的方法都有synchronized进行修饰,即Vector使用同步方法来实现。并且Vector的扩容量与ArrayList有所区别,ArrayList的默认扩容量为0.5倍,而Vector的默认扩容量则为1倍。

synchronizedCollection

对于Vector使用同步方法来实现锁机制而synchronizedCollection则是使用同步代码块来实现锁机制,但是,因为SynchronizedList只是使用同步代码块包裹了ArrayList的方法,而ArrayList和Vector中同名方法的方法体内容并无太大差异,所以在锁定范围和锁的作用域上两者并无却别。而在锁定的对象区别上,SynchronizedList的同步代码块锁定的是mutex对象,Vector锁定的是this对象。那么mutex对象又是什么呢? 其实SynchronizedList有一个构造函数可以传入一个Object,如果在调用的时候显示的传入一个对象,那么锁定的就是用户传入的对象。如果没有指定,那么锁定的也是this对象。也就是说synchronizedCollection可以自定义锁对象,而Vector锁的对象只能是this也就是本身。

CopyOnWriteArrayList

这个并发集合采用的写时复制,读写分离的思想来避免并发时产生的异常。

private E get(Object[] var1, int var2) {
return var1[var2];
}
public E get(int var1) {
return this.get(this.getArray(), var1);
}
public boolean add(E var1) {
ReentrantLock var2 = this.lock;
var2.lock();
boolean var6;
try {
Object[] var3 = this.getArray();
int var4 = var3.length;
Object[] var5 = Arrays.copyOf(var3, var4 + 1);
var5[var4] = var1;
this.setArray(var5);
var6 = true;
} finally {
var2.unlock();
}
return var6;
}

根据以上的源码我们可知,在进行写操作的时候将会事先加锁防止并发问题,然后对原集合进行拷贝一份并且在这份新拷贝的集合中进行数据处理。当数据处理完毕后才将旧集合替换为新集合。而对于读操作在写操作未完成时永远都是以未加锁的形式读取旧的集合。CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

优点:

  1. CopyOnWriteArrayList适合使用在读操作远远大于写操作的场景里,比如缓存。保证读的高性能,适用于以读为主的情况。使用了独占锁,支持多线程下的并发写。

    缺点:
  2. 内存占用问题。在集合进行add操作时内存里会同时驻扎两个对象的内存,旧的对象和新写入的对象。当CopyOnWriteArrayList处于占用内存较大时容易造成频繁GC问题。
  3. 数据一致性问题。CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性。所以如果你希望写入的的数据,马上能读到,请不要使用CopyOnWrite容器。【当执行add或remove操作没完成时,get获取的仍然是旧数组的元素】

java - 并发集合 Vector、synchronizedCollection、CopyOnWriteArrayList之间的区别。的更多相关文章

  1. Java并发集合(一)-CopyOnWriteArrayList分析与使用

    CopyOnWriteArrayList分析与使用 原文链接: http://ifeve.com/java-copy-on-write/ 一.Copy-On-Write Copy-On-Write简称 ...

  2. Java并发集合的实现原理

    本文简要介绍Java并发编程方面常用的类和集合,并介绍下其实现原理. AtomicInteger 可以用原子方式更新int值.类 AtomicBoolean.AtomicInteger.AtomicL ...

  3. Java 并发集合的实现原理

    http://www.codeceo.com/article/the-implementation-principle-of-java-concurrent-collection.html 阿凡卢   ...

  4. java并发集合知识点(二)

    我们平时写程序需要经常用到集合类,比如ArrayList.HashMap等,但是这些集合不能够实现并发运行机制,这样在服务器上运行时就会非常的消耗资源和浪费时间,并且对这些集合进行迭代的过程中不能进行 ...

  5. 转:Java并发集合

    引自:http://ifeve.com/concurrent-collections-1/ 并发集合(一)引言 声明:本文是< Java 7 Concurrency Cookbook>的第 ...

  6. Java并发指南14:Java并发容器ConcurrentSkipListMap与CopyOnWriteArrayList

    原文出处http://cmsblogs.com/ 『chenssy』 到目前为止,我们在Java世界里看到了两种实现key-value的数据结构:Hash.TreeMap,这两种数据结构各自都有着优缺 ...

  7. java 常用集合list与Set、Map区别及适用场景总结

     转载请备注出自于:http://blog.csdn.net/qq_22118507/article/details/51576319                  list与Set.Map区别及 ...

  8. java execute、executeQuery和executeUpdate之间的区别

    在用纯JSP做一个页面报警功能的时候习惯性的用executeQuery来执行SQL语句,结果执行update时就遇到问题,语句能执行,但返回结果出现问题,另外还忽略了executeUpdate的返回值 ...

  9. Java自学-集合框架 HashMap和Hashtable的区别

    HashMap和Hashtable之间的区别 步骤 1 : HashMap和Hashtable的区别 HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式 区别1: Hash ...

随机推荐

  1. Docker Compose搭建Redis一主二从三哨兵高可用集群

    一.Docker Compose介绍 https://docs.docker.com/compose/ Docker官方的网站是这样介绍Docker Compose的: Compose是用于定义和运行 ...

  2. 珠峰-cookie相关的东西

    ####  md5 #### #####

  3. Linux运维--实践-Rally

    1.rally简介 OpenStack Rally 是一个自动化测试工具,社区希望通过 Rally 来解答 "How does OpenStack work at scale?(如何规模化运 ...

  4. pikachu-XXE(xml external entity-injection)

    部分图片来自于网络,如有侵权,请联系我及时删除~ 一.XXE的概念 1.1 什么是xml xml是一种可拓展的标记语言,可以用来存储数据,例如:我们经常看到一些.xml的文件:它还可以用来传输数据,我 ...

  5. jQuery on 绑定的事件 执行两次

    $(".class1").on("click",".class2",function(){ alert('提示'); }); 上面代码,怎么 ...

  6. Ansible学习笔记(一):部署管理Windows机器遇到的一些坑

    在给国盛通上海测试环境做Ansible管理Windows服务器的时候,遇到了一些坑,Google解决掉了,特此记录,坑用红色标记. 一.环境说明 1.Ansible管理主机 操作系统:CentOS 7 ...

  7. 传智播客C++视频学习笔记(3)

    #include<iostream> using namespace std; //内存分区模型 //代码区,存放二进制代码,由操作系统进行管理 //全局区,存放全局变量.静态变量.常量( ...

  8. scanf 与fgets

    scanf: 1.以输入字符串也可以输入数字 . 2.遇到空格就停止.3.会有segmentation fault. fgets: 1.只能输入字符串.2.回车才会停止.3.不会有segmenntat ...

  9. char、vchar、nvarchar 的区别

    Unicode字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字符都用两个字节表示,即英文字符也是用两个字节表示 如果还为了这个纠结,就直接看看后面的解说,做决定吧. 一般如果用到中文或者其 ...

  10. VMware与Centos系统安装之重置root密码

    VMware与Centos系统安装之重置root密码   今日任务 1.Linux发行版的选择 2.vmware创建一个虚拟机(centos) 3.安装配置centos7 4.xshell配置连接虚拟 ...