一、CopyOnWriteArrayList简介
CopyOnWriteArrayList是Java中并发集合类之一,实现了List接口,通过对内部数组进行copy-on-write的方式来保证线程安全性。简单来说,就是在修改时先对当前数组进行复制,然后进行修改,最后将复制后的新数组赋值给当前数组。这种方式在读多写少的情况下能够提供比较好的读写性能。
二、CopyOnWriteArrayList线程安全机制
CopyOnWriteArrayList通过对内部数组进行复制,以分离写操作和读操作的锁,从而保证线程安全。在进行写操作时,首先对当前数组进行复制,然后针对新的数组进行修改,最后将新的数组赋值给当前数组,完成写操作。在读取操作时,直接读取当前数组即可,因为操作的是一个不可变的数组,读取时不存在线程安全问题。
三、CopyOnWriteArrayList的优缺点
3.1 优点
1、线程安全:由于在进行读写操作时,读操作对原始数组只进行读取,不会修改,所以读操作不需要进行锁定操作,可以同时进行,从而提高并发性。
2、适用于读多写少的场景:由于每次进行写操作时都需要进行数组复制,所以在写操作比较频繁的情况下CopyOnWriteArrayList的性能会比较低。但是在读操作比较频繁的情况下,由于读操作不需要使用锁,因此能够提供很好的性能。
3.2 缺点
1、内存占用:由于每次进行写操作都需要进行数组复制,因此需要占用较大的内存空间。
2、修改操作的延迟:在进行写操作时,需要先对原始数组进行复制,然后在复制的数组上进行修改,最后再将修改后的数组赋值给原始数组,这个过程需要一定的时间,因此可能会出现修改操作的延迟。
四、CopyOnWriteArrayList线程安全示例
import java.util.concurrent.CopyOnWriteArrayList; public class CopyOnWriteArrayListExample { private static final int THREAD_POOL_SIZE = 2; public static void main(String[] args) throws InterruptedException { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); //添加元素 list.add("Java"); list.add("Python"); list.add("C++"); //创建两个线程向list中添加元素 Runnable task = () -> { for (int i = 0; i < 100; i++) { list.add(Thread.currentThread().getName() + ":" + i); } }; //创建线程池 ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE); executorService.submit(task); executorService.submit(task); //等待所有线程执行完成 executorService.shutdown(); executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); //输出list中所有元素 for (String str : list) { System.out.println(str); } } }
上述示例代码通过创建两个线程向CopyOnWriteArrayList添加元素,由于CopyOnWriteArrayList的线程安全机制,在并发执行时不会出现线程安全问题,每个线程可以安全地执行写操作。