应优先使用 ArrayList 而非 Vector,因后者同步开销大、粗粒度锁致吞吐量低、不支持复合操作原子性,且已被 java.util.concurrent 替代;仅限遗留系统或单线程误用场景。

Vector 是线程安全的过时选择,除非你明确需要同步且无法改用 java.util.concurrent 包,否则一律优先用 ArrayList。
Vector 的 synchronized 方法到底有多重?
每个 public 方法(如 add()、get()、size())都加了 synchronized,连只读操作也不放过。这意味着:即使多个线程只读不写,也会排队等待锁,吞吐量明显低于 ArrayList;而且这种粗粒度锁无法组合多个操作(比如“检查是否存在再添加”),仍需额外同步块。
常见错误现象:ConcurrentModificationException 依然可能出现——因为迭代器不是 fail-fast 安全的,且多线程下即使没修改也可能因锁竞争导致状态不一致。
使用场景极窄:仅限遗留系统强制要求 Vector,或在单线程中误用(此时纯属性能浪费)。
立即学习“Java免费学习笔记(深入)”;
ArrayList 在多线程下怎么补足安全性?
它本身完全不处理线程安全,但这是设计使然——把同步策略交给上层,更灵活也更高效。
- 若需简单同步包装,用
Collections.synchronizedList(new ArrayList()):它只对方法调用加锁,不解决复合操作问题 - 若需高并发读写,直接用
CopyOnWriteArrayList(适合读多写少)或ConcurrentLinkedQueue(非 List 语义但无锁) - 若需原子性复合操作(如“不存在才添加”),必须自己用
synchronized块或ReentrantLock保护整个逻辑段
扩容机制和性能差异真的影响大吗?
两者默认初始容量都是 10,但扩容策略不同:Vector 默认翻倍(capacity * 2),ArrayList 是 oldCapacity + (oldCapacity >> 1)(即增 50%)。实际影响微乎其微——真正拖慢的是 Vector 的同步开销,不是扩容次数。
性能实测典型结果:在单线程下,ArrayList 添加 100 万元素比 Vector 快 2–3 倍;在多线程争抢下,差距可扩大到 10 倍以上。
兼容性注意:Vector 还保留着已废弃的 addElement()、firstElement() 等方法,这些在新代码里不应出现;而 ArrayList 严格遵循 List 接口,与 Stream、Collections 工具类无缝配合。
为什么不能靠 “Vector 更老 = 更稳定” 来选型?
“老” 不等于“稳”,而是“被替代”。JDK 1.2 引入 ArrayList 后,Vector 就被标记为遗留类;Java 5 加入 java.util.concurrent 后,它的线程安全价值彻底归零。现在连 Vector 的序列化格式都和 ArrayList 不一致(Vector 序列化时会写入 capacity,ArrayList 不写),跨版本反序列化可能出错。
容易被忽略的一点:IDE 和静态分析工具(如 SpotBugs)会把 Vector 当作代码坏味道标红——不是因为它不能运行,而是因为它暗示你可能没理解现代 Java 的并发模型。










