协慌网

登录 贡献 社区

为什么 Java Vector(和 Stack)类被视为过时或过时的?

为什么将 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 ,因此您无法对同步进行精细的控制。

ArrayListVector之间没有太大区别,但是您应该使用ArrayList

来自 API 文档。

从 Java 2 平台 v1.2 开始,对该类进行了改进以实现 List 接口,使其成为 Java Collections Framework 的成员。与新的集合实现不同,Vector 是同步的。

除了已经说明的使用 Vector 的答案外,Vector 还具有许多围绕 List 和 List 的枚举和元素检索方法,并且开发人员(尤其是那些在 1.2 之前学习过 Java 的人)可以倾向于使用它们。代码。尽管枚举速度更快,但它们不会检查迭代期间是否对集合进行了修改,这可能会导致问题,并且考虑到可能会选择 Vector 进行同步 - 伴随有来自多个线程的访问,这使其成为一个特别有害的问题。这些方法的使用也将大量代码耦合到 Vector,以至于用不同的 List 实现替换它并不容易。