Collections.synchronizedXXX 同步机制

Collections.synchronizedXXX 同步机制
LiuxzCollections.synchronizedXXX 是 Java 集合框架中用于将非线程安全的集合转换为线程安全集合的工具方法,主要作用是通过 同步机制 保证多线程环境下集合操作的安全性。以下是对这类方法的总结:
1. 核心功能
- 线程安全转换:将非线程安全的集合(如
ArrayList、HashMap、HashSet等)包装为线程安全的版本,避免多线程并发操作时出现数据不一致或异常(如ConcurrentModificationException)。 - 同步实现方式:通过 包装器模式,在原集合的所有方法(如
add、remove、get等)外层添加synchronized同步块,确保同一时刻只有一个线程能执行集合的方法。
2. 常用方法及对应集合
| 方法 | 作用 | 对应的非线程安全集合 | 线程安全包装后的类型 |
|---|---|---|---|
synchronizedList(List<T>) |
将 List 转换为线程安全集合 | ArrayList、LinkedList |
同步化的 List |
synchronizedSet(Set<T>) |
将 Set 转换为线程安全集合 | HashSet、LinkedHashSet |
同步化的 Set |
synchronizedMap(Map<K,V>) |
将 Map 转换为线程安全集合 | HashMap、LinkedHashMap |
同步化的 Map |
synchronizedSortedSet(SortedSet<T>) |
将有序 Set 转换为线程安全集合 | TreeSet |
同步化的 SortedSet |
synchronizedSortedMap(SortedMap<K,V>) |
将有序 Map 转换为线程安全集合 | TreeMap |
同步化的 SortedMap |
synchronizedCollection(Collection<T>) |
将任意 Collection 转换为线程安全 | 所有 Collection 实现类 |
同步化的 Collection |
3. 使用注意事项
迭代操作的线程安全:
虽然
synchronizedXXX方法保证了单个方法的线程安全,但 迭代操作(如for-each、iterator)仍需手动加锁。因为迭代过程涉及多次方法调用(如hasNext()、next()),若不加锁,其他线程可能在迭代中修改集合,导致ConcurrentModificationException。示例:
1
2
3
4
5
6
7List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// 迭代时需手动同步
synchronized (syncList) {
for (String s : syncList) {
// 迭代操作
}
}性能问题:
由于所有方法都通过
synchronized加锁,本质是 悲观锁,多线程高并发场景下可能因锁竞争导致性能瓶颈。此时推荐使用java.util.concurrent包下的并发集合(如ConcurrentHashMap、CopyOnWriteArrayList),它们采用更高效的并发策略(如分段锁、写时复制)。原集合的可见性:
包装后的线程安全集合会代理所有操作到原集合,因此 不应再直接操作原集合,否则会破坏线程安全性。
null 值支持:
包装后的集合是否支持
null元素,取决于原集合(如synchronizedMap(HashMap)支持null键值,而synchronizedMap(TreeMap)不支持)。
4. 适用场景
多线程环境下对集合的操作频率低、并发量小,且需要简单实现线程安全的场景。
需兼容旧有非线程安全集合,快速改造为线程安全的临时方案。
不适合高并发场景(推荐用
java.util.concurrent并发集合),也不适合需要精细同步控制的场景。
总结
Collections.synchronizedXXX 是一种简单的线程安全集合实现方式,通过全局同步保证安全性,但存在性能限制和迭代需手动加锁的问题。使用时需根据并发量和性能需求,选择合适的集合类型。




