java - 并发集合 Vector、synchronizedCollection、CopyOnWriteArrayList之间的区别。
概要
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容器也是一种读写分离的思想,读和写不同的容器。
优点:
- CopyOnWriteArrayList适合使用在读操作远远大于写操作的场景里,比如缓存。保证读的高性能,适用于以读为主的情况。使用了独占锁,支持多线程下的并发写。
缺点: - 内存占用问题。在集合进行add操作时内存里会同时驻扎两个对象的内存,旧的对象和新写入的对象。当CopyOnWriteArrayList处于占用内存较大时容易造成频繁GC问题。
- 数据一致性问题。CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性。所以如果你希望写入的的数据,马上能读到,请不要使用CopyOnWrite容器。【当执行add或remove操作没完成时,get获取的仍然是旧数组的元素】
java - 并发集合 Vector、synchronizedCollection、CopyOnWriteArrayList之间的区别。的更多相关文章
- Java并发集合(一)-CopyOnWriteArrayList分析与使用
CopyOnWriteArrayList分析与使用 原文链接: http://ifeve.com/java-copy-on-write/ 一.Copy-On-Write Copy-On-Write简称 ...
- Java并发集合的实现原理
本文简要介绍Java并发编程方面常用的类和集合,并介绍下其实现原理. AtomicInteger 可以用原子方式更新int值.类 AtomicBoolean.AtomicInteger.AtomicL ...
- Java 并发集合的实现原理
http://www.codeceo.com/article/the-implementation-principle-of-java-concurrent-collection.html 阿凡卢 ...
- java并发集合知识点(二)
我们平时写程序需要经常用到集合类,比如ArrayList.HashMap等,但是这些集合不能够实现并发运行机制,这样在服务器上运行时就会非常的消耗资源和浪费时间,并且对这些集合进行迭代的过程中不能进行 ...
- 转:Java并发集合
引自:http://ifeve.com/concurrent-collections-1/ 并发集合(一)引言 声明:本文是< Java 7 Concurrency Cookbook>的第 ...
- Java并发指南14:Java并发容器ConcurrentSkipListMap与CopyOnWriteArrayList
原文出处http://cmsblogs.com/ 『chenssy』 到目前为止,我们在Java世界里看到了两种实现key-value的数据结构:Hash.TreeMap,这两种数据结构各自都有着优缺 ...
- java 常用集合list与Set、Map区别及适用场景总结
转载请备注出自于:http://blog.csdn.net/qq_22118507/article/details/51576319 list与Set.Map区别及 ...
- java execute、executeQuery和executeUpdate之间的区别
在用纯JSP做一个页面报警功能的时候习惯性的用executeQuery来执行SQL语句,结果执行update时就遇到问题,语句能执行,但返回结果出现问题,另外还忽略了executeUpdate的返回值 ...
- Java自学-集合框架 HashMap和Hashtable的区别
HashMap和Hashtable之间的区别 步骤 1 : HashMap和Hashtable的区别 HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式 区别1: Hash ...
随机推荐
- win10配置CUDA+Tensorflow2.0的一些经验
目录 问题描述 安装 tensorflow-cpu-2.0 编译 Nvidia Samples 问题描述 网上已经很多关于配置CUDA的文章,自己这篇文章只是个大致的安装步骤,文章重点是安装和配置的一 ...
- 7.【Spring Cloud Alibaba】微服务的用户认证与授权
有状态 vs 无状态 有状态 那么Session在何时创建呢? 当然还是在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法,而在Java中是通过调用HttpServ ...
- C语言中的弱符号(weak)用法及实例
一 符号概念: 在C语言中,有强符号和弱符号,符号简单来说就是函数.变量的名字,对于全局(非局部.非static)的函数和变量,能不能重名是有一定规矩的,强.弱符号就是针对这些全局函数和变量来说的. ...
- .Net core webapi使用httpClient发送异步请求遇到TaskCanceledException: A task was canceled
前言:本人最近较多使用.net core的项目,最近在使用httpClient发送请求的时候,遇到服务器处理时间较长时,就老是会报异常:TaskCanceledException: A task wa ...
- C#的多线程简洁笔记
New Thread(()=>{}).Start(); //匿名线程 Thread Ntd = new Thread(T1); Ntd.IsBackground = true; //后台线程 N ...
- html基本介绍,了解html与css,html语法和结构
一般来说,制作自己第一个网页通常书写的文字是"hello world!你好,全世界",代码如下展示: <!DOCTYPE html> <html lang=&qu ...
- Happycorp:1 Vulnhub Walkthrough
靶机链接: https://www.vulnhub.com/entry/happycorp-1,296/ 网络主机扫描::: 主机端口扫描: NFS文件系统,尝试挂载试试 mount -t nfs 1 ...
- Binder基本使用
Android开发中,Binder是一种跨进程通信方式,而使用AIDL可以实现Binder的工作. 如何使用它是了解它的第一步,本文章主要记录使用Binder的一些步骤.(代码思路参考<Andr ...
- 使用MuMu模拟器调试AndroidStudio项目
1.安装一款安卓模拟器 本例使用网易MuMu模拟器,因为目前网络上这类模拟器只有mumu的安卓版本是最新的,为6.0,安卓自带的Virtual Device虽然有很新的版本,但如果pc配置不是很高 ...
- 正则表达式中的exec()方法
推荐该博主的内容链接: https://blog.csdn.net/ddwddw4/article/details/84658398?ops_request_misc=%7B%22request%5F ...