ArrayList非线程安全,多线程操作易出错;读多写少用CopyOnWriteArrayList,写多用Collections.synchronizedList并手动同步遍历,高并发慎用Vector,复杂场景选ConcurrentHashMap或BlockingQueue等。

ArrayList 本身不加锁,多线程同时 add、remove 或遍历时,会因 size 更新非原子 和 扩容过程未同步 导致数据丢失、数组越界或 ConcurrentModificationException。替换成并发容器不是简单换类名,而是要按场景选对方案。
读多写少场景:优先用 CopyOnWriteArrayList
适合监听器列表、配置项缓存、白名单等读远多于写的场合。
- 每次写操作(add/remove/set)都会复制整个底层数组,读操作完全无锁,迭代器不会抛 ConcurrentModificationException
- 遍历时其他线程写入不影响当前快照,安全性高、使用简单
- 注意:写开销大、内存占用高、不能保证实时一致性;不适合高频写或大数据量
需要强一致性且写操作较多:考虑 Collections.synchronizedList
对已有 ArrayList 做轻量包装,兼容老代码,但要注意使用边界。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 单个方法调用(如 get、add、remove)是线程安全的,底层加了 synchronized(mutex)
- 遍历必须手动加锁:synchronized(list) { Iterator it = list.iterator(); ... }
- 复合操作(如“先检查再添加”)仍需外部同步,因为 contains() 和 add() 是两次独立调用
高并发写+读均衡场景:避免 Vector,慎用 synchronizedList
Vector 虽线程安全,但所有 public 方法都加 synchronized,锁粒度太粗,吞吐低,已基本被弃用。
立即学习“Java免费学习笔记(深入)”;
- 默认扩容为 2 倍,比 ArrayList 的 1.5 倍更耗内存
- Enumeration 和 Iterator 都 fail-fast,遍历同样要额外加锁
- 除非维护遗留系统,否则不推荐新项目使用
更复杂需求:转向 java.util.concurrent 其他工具
如果业务涉及条件判断、批量更新、延迟处理等,单一 List 容器可能不够用。
- 需要原子性复合操作?考虑用 ConcurrentHashMap + 自定义逻辑,或封装成线程安全的工具类
- 写操作带顺序依赖?可搭配 BlockingQueue 或使用 ReentrantLock 控制临界区
- 仅需遍历时安全?也可用 Collections.unmodifiableList(new ArrayList(original)) 生成只读快照

















