Collections.synchronizedList

Collections 工具类提供一个 synchronizedList 方法,把一个 List 实例装饰成线程安全的。实际上返回的是 Collections.SynchronizedList 内部类,它持有一个原始 List 的引用,并在所有方法调用上加 synchronized,从而保证线程安全。但是迭代器不是线程安全,用户必须手动加锁。

这正是装饰器模式的典型应用:在运行时对已有对象进行功能增强(加锁),而不改变其接口定义。

List<Integer> syncList = Collections.synchronizedList(new ArrayList<>());

Vector

Vector 在源码里,大多数对内部数组的操作方法(addremoveget)都加了 synchronized 修饰来保证互斥访问。同一时刻只有一个线程能执行这些方法,从而避免了数据竞争和不一致。

虽然方法是同步的,但 Vector 的迭代器(Iterator)不是线程安全的。如果要安全遍历,必须手动加锁:

synchronized (vector) {
    Iterator<Integer> it = vector.iterator();
    while (it.hasNext()) {
        System.out.println(it.next());
    }
}

CopyOnWriteArrayList

CopyOnWriteArrayListjava.util.concurrent 包下的一个线程安全的 List 实现。它的核心思想是写时复制

  • 读操作:不加锁,直接基于底层数组读取,速度快、线程安全;

  • 写操作:先复制一份底层数组,在副本上修改,修改完成后再把引用切换过去。

因此,它非常适合读多写少的场景,性能比 Vector 高很多。但是读线程可能读到旧数组(快照),对“实时性”要求高的场景不适用。

List<Integer> list = new CopyOnWriteArrayList<>();

ConcurrentHashMap