java arraylist 在多线程中不安全,因为它的读写操作没有同步机制,会导致数据覆盖或并发修改异常。要安全使用,最简单的方法是调用 collections.synchronizedlist() 包装它,或者直接使用 copyonwritearraylist。前者适合写少读多的场景,后者适合读多写少的场景。

Collections.synchronizedList() 的线程安全实现原理
该方法返回一个包装类,内部持有原始列表和一把锁对象。每次访问元素时,都会先获取这把锁,确保同一时刻只有一个线程能操作列表。但要注意,迭代器不是线程安全的,必须在外部手动加锁才能遍历。

import java.util.*;
public class SyncListDemo {
public static void main(String[] args) {
List<string> list = Collections.synchronizedList(new ArrayList());
list.add("A");
synchronized (list) {
Iterator<string> it = list.iterator();
while (it.hasNext()) System.out.println(it.next());
}
}
}</string></string>
CopyOnWriteArrayList 的读写分离策略
这个类在写入时会复制一份底层数组,新元素写入副本后再替换原引用。这样读操作完全不需要加锁,性能极高,但写操作会有内存开销和短暂的数据不一致。

import java.util.*;
public class COWListDemo {
public static void main(String[] args) {
CopyOnWriteArrayList<string> list = new CopyOnWriteArrayList();
list.add("B");
for (String s : list) System.out.println(s);
}
}</string>
基于 CopyOnWriteArrayList 写入时的数组复制行为
当调用 add() 方法时,它会检查当前数组长度,然后创建一个新的数组,将旧元素拷贝过去,再添加新元素,最后通过 volatile 变量更新引用。这个过程是原子性的,保证了读的可见性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











