Vector的add方法比ArrayList慢,因为每次调用都需获取和释放对象锁,而ArrayList完全无锁;Collections.synchronizedList并非Vector平替,因二者均不保证复合操作线程安全,且Vector迭代器非线程安全。

Vector的add方法为什么比ArrayList慢
因为每次调用 add 都会触发内部同步块,哪怕你只是往空集合里加一个元素。JVM必须为每个操作获取和释放对象锁,而这个开销在高并发下不明显,在单线程里反而更拖后腿。
- Vector 的
add底层是synchronized方法,等价于synchronized(this) { ... } - ArrayList 的
add完全无锁,扩容时也只是普通数组复制 - 实测:单线程循环添加 10 万条数据,Vector 通常比 ArrayList 慢 2–3 倍
为什么Collections.synchronizedList(new ArrayList())不是Vector的平替
它只保证单个方法调用的原子性,不保证复合操作线程安全 —— 这点和 Vector 一样,但很多人误以为“包装了就万事大吉”。
- 比如
if (list.size() > 0) list.remove(0),无论用 Vector 还是Collections.synchronizedList,都可能在size()和remove()之间被其他线程修改 - Vector 的迭代器(
iterator())不是线程安全的,遍历时仍可能抛ConcurrentModificationException - 真正需要多线程协作读写时,应该考虑
CopyOnWriteArrayList或ConcurrentHashMap替代方案
Vector的capacityIncrement参数实际影响哪些场景
它只在容量不够、需要扩容时起作用,决定“下次扩容多加多少”,但 JDK 8+ 默认值是 0,意味着按 2 倍增长 —— 和 ArrayList 一致,除非你显式构造时传入非零值。
- 构造
new Vector(10, 5):初始容量 10,每次扩容加 5;而new Vector(10)实际等价于new Vector(10, 0),扩容策略变成翻倍 - ArrayList 没有类似参数,扩容逻辑固定:旧容量 * 1.5(JDK 7+),不可配置
- 如果业务能预估大小,直接用
new ArrayList(expectedSize)更可控,Vector 的capacityIncrement很少真有用武之地
什么时候还不得不碰Vector
基本只出现在维护老代码、对接遗留 API 或某些特定框架的强制类型要求里。新项目几乎没理由选它。
立即学习“Java免费学习笔记(深入)”;
- Swing 的
DefaultListModel内部用 Vector 存储,如果你重写它的子类并暴露底层集合,可能被迫处理 Vector - 一些银行/电信老系统接口定义返回类型是
Vector<string></string>,连泛型都没,改接口成本远高于忍着用 - 注意:即使必须用 Vector,也别依赖它的同步能力做业务并发控制 —— 锁粒度太粗,容易成为瓶颈
Vector 的同步机制是粗粒度的、不可拆分的,而且没法关掉。真正要线程安全,得从设计上隔离共享状态,而不是靠容器自己扛锁。









