简介
CopyOnWriteArrayList 是 Java 并发集合框架中的一种线程安全列表。它是一个 ArrayList 的子类,旨在在多线程环境中高效地处理并发修改。
工作原理
CopyOnWriteArrayList 使用了一种称为 "写时复制" 的技术。这意味着只有在对列表进行结构性修改(例如添加或删除元素)时才会创建底层数组的新副本。在读取列表时,它直接使用原始数组,从而提高了并发读取的性能。
线程安全性
CopyOnWriteArrayList 是线程安全的,这意味着它可以安全地用于多线程环境中,而无需额外的同步。这是因为每次进行结构性修改时,都会创建一个底层数组的新副本,这确保了对列表的并发访问不会导致数据损坏。
性能权衡
虽然 CopyOnWriteArrayList 提供了线程安全性,但它在写入操作方面比传统的 ArrayList 慢。这是因为每次进行结构性修改时,它都需要创建底层数组的新副本。对于频繁写入的列表,这可能会导致性能下降。
使用场景
CopyOnWriteArrayList 适用于以下场景:
- 需要在多线程环境中安全地访问和修改列表。
- 读取操作远多于写入操作。
- 列表的大小相对较小,或者写入操作不频繁。
示例
以下是如何在 Java 中使用 CopyOnWriteArrayList:
import java.util.concurrent.CopyOnWriteArrayList;
public class Example {
public static void main(String[] args) {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("John");
list.add("Mary");
list.add("Bob");
// 多个线程可以并发读取列表
Thread thread1 = new Thread(() -> {
for (String name : list) {
System.out.println(name);
}
});
Thread thread2 = new Thread(() -> {
list.add("Alice");
});
thread1.start();
thread2.start();
// 等待线程完成
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 列表现在包含 4 个元素
System.out.println(list); // 输出:[John, Mary, Bob, Alice]
}
}
与 ArrayList 的比较
特性 | CopyOnWriteArrayList | ArrayList |
---|---|---|
线程安全性 | 是 | 不是 |
写入性能 | 慢 | 快 |
读取性能 | 快 | 快 |
内存使用 | 高 | 低 |
适用于 | 并发读取多于写入 | 写入操作频繁 |
总结
CopyOnWriteArrayList 是 Java 并发集合框架中一种非常有用的线程安全列表。它在需要在多线程环境中安全地访问和修改列表的情况下非常有用,尤其是当读取操作远多于写入操作时。但是,对于频繁写入的列表,它可能比传统的 ArrayList 慢。