package com.ljn.base;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 总述:
* 1.ArrayListi不是线程安全的,CopyOnWriteArrayList是线程安全的。
* 2.ArrayListi读的时候不能写:在遍历时不能执行list.remove,list.add;但可以执行iterator.remove。
* CopyOnWriteArrayList则相反:可执行list.remove,list.add,但不能执行iterator.remove。
* 3.CopyOnWriteArrayList用在“读比写频繁得多”的情形下。例如多个线程要遍历,而只有少数线程要写。
* 这样就会有一个问题:读的时候可以写吗?可以,因为:
* 4.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();
}
}
5.CopyOnWriteArrayList当前线程开始遍历(创建Iterator)时,只会看到当前数组的元素,在遍历过程中,
如果原数组发生了变化(其他线程执行add或remove),当前线程是看不到的。以下是创建Iterator的源码:
private final Object[] snapshot;
private int cursor;
private COWIterator(Object[] elements, int initialCursor) {
cursor = initialCursor;
snapshot = elements;
}
*/
public class CopyOnWriteArrayListTest {
public final static void main(String args[]) {
testCopyOnWriteArrayList();
testArrayList();
}
private static void testCopyOnWriteArrayList() {
List<String> list = new CopyOnWriteArrayList<String>();
list.add("a");
list.add("b");
Iterator<String> iterator = list.iterator();
int j = 0;
//will output current array: "a" and "b"
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
list.add("c" + (j++)); //操作成功。但不会马上反映在本次while循环中,因为:
/*
An array you are looking at currently (lets say your iterator) will never change.
When you read from an array you are reading it as it was when you started reading.
If the CopyOnWriteArrayList changes by another thread, the array you're currently observing will not be affected
*/
if (item.equals("b")) {
list.remove(item); //ok
}
//iterator.remove(); //UnsupportedOperationException
}
System.out.println(list); //[a, c0, c1]
}
private static void testArrayList() {
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("z");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
iterator.remove(); //ok
//list.remove(item); //ConcurrentModificationException
//list.add("c"); //ConcurrentModificationException
//iterator.add(); //does not have this method on Iterator
}
System.out.println(list); //empty list: []
}
}
分享到:
相关推荐
ArrayList是一种以数组实现的List,它实现了List, RandomAccess, Cloneable, Serializable接口。 实现List接口表示它可以支持删除、添加和查找等操作。 实现RandomAccess接口表示它可以支持随机访问(强调一点,并不...
Java并发容器CopyOnWriteArrayList是Java并发包中提供的一个并发容器,实现了线程安全且读操作无锁的ArrayList,写操作则通过创建底层数组的新副本来实现。这种读写分离的并发策略使得CopyOnWriteArrayList容器允许...
如果需要在并发环境中使用,可以选择使用Collections.synchronizedList()方法将ArrayList转换为线程安全的列表,或者使用并发集合如CopyOnWriteArrayList。 ArrayList的效率特点在于随机访问速度快,因为可以通过...
若需在多线程环境中使用,可以考虑使用Collections.synchronizedList对ArrayList进行包装,或者使用线程安全的CopyOnWriteArrayList。 ArrayList的迭代器(Iterator)允许我们以任意顺序遍历元素,并且支持remove...
如果需要线程安全,可以考虑使用`Collections.synchronizedList()`将ArrayList转换为线程安全的列表,或者使用`CopyOnWriteArrayList`类。 ArrayList的容量会随着元素数量的增加自动扩展。默认情况下,当容量达到...
如果需要线程安全,可以选择使用`java.util.concurrent.CopyOnWriteArrayList`。 4. 常用方法: - `add(E element)`: 在列表末尾添加一个元素。 - `add(int index, E element)`: 在指定位置插入一个元素。 - `...
这种情况下,可以通过诸如Collections.synchronizedList等包装器方法,或者使用CopyOnWriteArrayList等线程安全的替代实现来保证线程安全。 ArrayList提供了三种构造方法。一种是无参构造方法,默认初始容量为10;...
如果需要在多线程环境下使用,可以考虑使用`Collections.synchronizedList`方法对`ArrayList`进行同步,或者使用`CopyOnWriteArrayList`。 4. **效率比较**:相比于`LinkedList`,`ArrayList`在插入和删除元素时...
此外,对于大数据量的情况,考虑使用并发集合,如ConcurrentLinkedQueue或CopyOnWriteArrayList,以提高多线程环境下的性能。 总的来说,理解ArrayList和LinkedList的基本特性和应用场景,以及如何处理与之相关的...
如果需要线程安全的列表,应使用`CopyOnWriteArrayList`。 7. **ArrayList与LinkedList的比较** - ArrayList更适合于随机访问,插入和删除在中间位置较慢。 - LinkedList适合于频繁的插入和删除,但随机访问性能...
对于并发场景,可以使用CopyOnWriteArrayList(线程安全的ArrayList变体)和ConcurrentHashMap(线程安全的HashMap变体)。 总之,ArrayList和HashMap是Java集合框架中的重要组件,理解它们的工作原理和适用场景,...
当然,现代Java版本推荐使用`java.util.concurrent`包下的并发集合,如`CopyOnWriteArrayList`,它们在多线程环境下提供了更好的性能和设计。 总之,理解ArrayList、LinkedList和Vector的内部工作原理和性能特征,...
Java中的`CopyOnWriteArrayList`是一个线程安全的列表实现,特别适合于高并发环境下的读多写少的场景。这个类的名字暗示了其工作原理:在修改(写入)时复制原有的数组,然后在新的数组上进行操作,最后将新数组替换...
在实际应用中,我们还应该考虑线程安全问题,尤其是在多线程环境下,可能需要使用Collections.synchronizedList()来同步ArrayList,或者使用CopyOnWriteArrayList避免并发修改引发的问题。此外,为了提高代码的...
然而,对于需要频繁修改列表的场景,CopyOnWriteArrayList的效率可能会低于其他并发控制机制,如使用`synchronized`修饰的ArrayList或使用`Collections.synchronizedList()`创建的同步列表。在选择数据结构时,...
1. 线程安全:ArrayList不是线程安全的,如果在多线程环境下同时操作ArrayList,需要使用Collections.synchronizedList()方法进行同步,或者使用并发集合如CopyOnWriteArrayList。 2. 空指针异常:调用get、set等...
在Java中,CopyOnWriteArrayList(写入时复制数组列表)是线程安全的集合类,它实现了List接口,并使用了"写入时复制"的...这样,在并发修改时,可以避免读取和写入同时进行,从而避免了传统ArrayList的线程同步问题。
1. **线程不安全**: ArrayList不是线程安全的,如果在多线程环境下操作ArrayList,需要同步或使用CopyOnWriteArrayList。 2. **扩容机制**: 当ArrayList达到其容量限制时,会自动扩容。默认容量为10,每次扩容大约...
在多线程环境下,要么使用`synchronized`方法,要么使用`CopyOnWriteArrayList`(线程安全但不支持修改操作)。 - 使用线程安全的ArrayList可能会降低性能,因为每次操作都需要进行同步。 总的来说,ArrayList是...