← 返回首页
ArrayList与CopyOnWriteArrayList的区别
发表时间:2023-04-07 10:37:48
ArrayList与CopyOnWriteArrayList的区别

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