Collections.synchronizedXxx()仅保证单个方法调用线程安全,不支持复合操作原子性;迭代需手动同步;推荐优先使用ConcurrentHashMap、CopyOnWriteArrayList等并发集合。
Java中Collections.synchronizedXxx()方法本身是线程安全的,但**仅限于单个操作层面**——它不能保证复合操作的原子性,因此在实际多线程场景中容易出错,需谨慎使用。
例如Collections.synchronizedList(new ArrayList())会对add()、get()、size()等每个方法加锁(内部使用对象自身作为锁),确保这些调用不会被并发干扰。但像“检查是否存在再添加”这种两步操作:
if (!list.contains(e)) list.add(e);中间可能被其他线程插入相同元素,导致重复——因为contains()和add()是两次独立加锁操作,锁已释放。
同步集合的iterator()、toArray()等方法**不自动加锁**。直接遍历时可能抛ConcurrentModificationException或读到脏数据:
for (Object o : syncList) { ... }(隐式调用iterator(),无同步)synchronized (syncList) { for (Object o : syncList) { ... } }
除非遗留系统受限,否则优先选用java.util.concurrent包中的原生并发集合:
CopyOnWriteArrayList:适合读多写少、允许迭代期间写入的场景ConcurrentHashMap:支持高并发读写,分段锁或CAS优化,性能远超Collections.synchronizedMap()
BlockingQueue实现类(如LinkedBlockingQueue):适用于生产者-消费者模型所有Collections.synchronize返回的包装器,其内部锁是传入的原始集合对象(如
dXxx()new ArrayList()实例)。这意味着:
synchronizedXxx()包装,它们仍共享同一把锁,能协同互斥syncList,另一个直接操作rawList),则完全失去同步保障