ArrayList与CopyOnWriteArrayList的区别。
1.ArrayList的线程不安全
ArrayList可以看作是能够自动增长容量的数组,ArrayList底层的实现是Array,故ArrayList的容量可以扩展,但是需要连续的内存空间。 ArrayList是线程不安全的,在多线程并发的情景下,会造成数据不一致的问题,那么这种情况下,可以使用Collections.synchronizedList()将ArrayList转为线程安全的,或者使用CopyOnWriteArrayList。
2.CopyOnWriteArrayList
CopyOnWriteArrayList和 ArrayList一样,也是通过数组实现的,但确是线程安全容器(相对于ArrayList),增加删除等写操作通过加锁的形式保证数据一致性,通过复制新集合的方式解决遍历迭代的问题。
CopyOnWriteArrayList的特点:
实例:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
public class CopyOnWriteArrayListDemo {
public static void main(String[] args) throws Exception {
final List<Integer> list = new ArrayList<Integer>();
//final List<Integer> list = new CopyOnWriteArrayList<Integer>();
CountDownLatch countDownLatch = new CountDownLatch(2);
// 线程A将0-1000添加到list
new Thread(() -> {
for (int i = 0; i < 1000; i++) {
list.add(i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
countDownLatch.countDown();
}).start();
// 线程B将1000-2000添加到列表
new Thread(() -> {
for (int i = 1000; i < 2000; i++) {
list.add(i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
countDownLatch.countDown();
}).start();
countDownLatch.await();
System.out.println("list集合的元素个数为:" + list.size());
}
}
运行结果不等于2000,说明ArrayList的add方法不是线程安全的:
list集合的元素个数为:1994
替换为CopyOnWriteArrayList后,结果为:
list集合的元素个数为:2000