概要
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 获取的仍然是旧数组的元素]
来源: http://www.bubuko.com/infodetail-3393702.html