为什么将 Java Vector 视为遗留类(已过时或已过时)?
使用并发时,使用它无效吗?
而且,如果我不想手动同步对象,而只想使用线程安全的集合而不需要创建基础数组的新副本(就像CopyOnWriteArrayList
一样),那么使用Vector
吗?
Stack
Vector
的子类,该怎么办呢?
Vector
在每个单独的操作上同步。那几乎从来不是你想要做的。
通常,您要同步整个操作序列。同步单个操作既不安全( Vector
进行迭代,则仍然需要锁,以避免其他人同时更改集合,这将导致迭代线程中ConcurrentModificationException
速度较慢(为什么一次就够了,为什么要反复取出锁)?
当然,即使您不需要时,它也具有锁定的开销。
基本上,在大多数情况下,这是一种非常有缺陷的同步方法。正如Brian Henk 先生所指出的那样,您可以使用诸如Collections.synchronizedList
Vector
结合了 “调整大小的数组” 集合实现与 “同步每个操作” 位的事实,这是不良设计的另一个例子。装饰方法使关注点更清晰地分离。
至于Stack
等效项 - 我先来看Deque
/ ArrayDeque
。
Vector 是 1.0 的一部分 - 原始实现有两个缺点:
1. 命名:向量实际上只是可以作为数组访问的列表,因此它应该被称为ArrayList
(它是 Java 1.2 Collections 替代Vector
)。
2. 并发性:所有get()
, set()
方法都是synchronized
,因此您无法对同步进行精细的控制。
ArrayList
和Vector
之间没有太大区别,但是您应该使用ArrayList
。
来自 API 文档。
从 Java 2 平台 v1.2 开始,对该类进行了改进以实现 List 接口,使其成为 Java Collections Framework 的成员。与新的集合实现不同,Vector 是同步的。
除了已经说明的使用 Vector 的答案外,Vector 还具有许多围绕 List 和 List 的枚举和元素检索方法,并且开发人员(尤其是那些在 1.2 之前学习过 Java 的人)可以倾向于使用它们。代码。尽管枚举速度更快,但它们不会检查迭代期间是否对集合进行了修改,这可能会导致问题,并且考虑到可能会选择 Vector 进行同步 - 伴随有来自多个线程的访问,这使其成为一个特别有害的问题。这些方法的使用也将大量代码耦合到 Vector,以至于用不同的 List 实现替换它并不容易。