Collections.synchronizedXXX 同步机制

Collections.synchronizedXXX 是 Java 集合框架中用于将非线程安全的集合转换为线程安全集合的工具方法,主要作用是通过 同步机制 保证多线程环境下集合操作的安全性。以下是对这类方法的总结:

1. 核心功能

  • 线程安全转换:将非线程安全的集合(如 ArrayListHashMapHashSet 等)包装为线程安全的版本,避免多线程并发操作时出现数据不一致或异常(如 ConcurrentModificationException)。
  • 同步实现方式:通过 包装器模式,在原集合的所有方法(如 addremoveget 等)外层添加 synchronized 同步块,确保同一时刻只有一个线程能执行集合的方法。

2. 常用方法及对应集合

方法 作用 对应的非线程安全集合 线程安全包装后的类型
synchronizedList(List<T>) 将 List 转换为线程安全集合 ArrayListLinkedList 同步化的 List
synchronizedSet(Set<T>) 将 Set 转换为线程安全集合 HashSetLinkedHashSet 同步化的 Set
synchronizedMap(Map<K,V>) 将 Map 转换为线程安全集合 HashMapLinkedHashMap 同步化的 Map
synchronizedSortedSet(SortedSet<T>) 将有序 Set 转换为线程安全集合 TreeSet 同步化的 SortedSet
synchronizedSortedMap(SortedMap<K,V>) 将有序 Map 转换为线程安全集合 TreeMap 同步化的 SortedMap
synchronizedCollection(Collection<T>) 将任意 Collection 转换为线程安全 所有 Collection 实现类 同步化的 Collection

3. 使用注意事项

  • 迭代操作的线程安全

    虽然 synchronizedXXX 方法保证了单个方法的线程安全,但 迭代操作(如 for-eachiterator)仍需手动加锁。因为迭代过程涉及多次方法调用(如 hasNext()next()),若不加锁,其他线程可能在迭代中修改集合,导致 ConcurrentModificationException

    示例:

    1
    2
    3
    4
    5
    6
    7
    List<String> syncList = Collections.synchronizedList(new ArrayList<>());
    // 迭代时需手动同步
    synchronized (syncList) {
    for (String s : syncList) {
    // 迭代操作
    }
    }
  • 性能问题

    由于所有方法都通过 synchronized 加锁,本质是 悲观锁,多线程高并发场景下可能因锁竞争导致性能瓶颈。此时推荐使用 java.util.concurrent 包下的并发集合(如 ConcurrentHashMapCopyOnWriteArrayList),它们采用更高效的并发策略(如分段锁、写时复制)。

  • 原集合的可见性

    包装后的线程安全集合会代理所有操作到原集合,因此 不应再直接操作原集合,否则会破坏线程安全性。

  • null 值支持

    包装后的集合是否支持 null 元素,取决于原集合(如 synchronizedMap(HashMap) 支持 null 键值,而 synchronizedMap(TreeMap) 不支持)。

4. 适用场景

  • 多线程环境下对集合的操作频率低、并发量小,且需要简单实现线程安全的场景。

  • 需兼容旧有非线程安全集合,快速改造为线程安全的临时方案。

  • 不适合高并发场景(推荐用 java.util.concurrent 并发集合),也不适合需要精细同步控制的场景。

总结

Collections.synchronizedXXX 是一种简单的线程安全集合实现方式,通过全局同步保证安全性,但存在性能限制和迭代需手动加锁的问题。使用时需根据并发量和性能需求,选择合适的集合类型。