为什么Java Vector(和Stack)类被认为已过时或已弃用?

问题

为什么Java Vector被认为是遗留类,已过时或已弃用?

在使用并发时,它的使用是否有效?

如果我不想手动同步对象而只想使用线程安全的集合而不需要制作底层数组的新副本(如CopyOnWriteArrayList那样),那么使用Vector是否合适?

那么Stack,它是Vector的一个子类呢,我应该用什么代替呢?


#1 热门回答(600 赞)

Vector在每个单独的操作上同步。这几乎不是你想要做的。

通常,你希望同步整个操作序列。同步单个操作都不太安全(例如,如果你迭代一个Vector,你仍然需要取出一个锁来避免其他人同时更改集合,这会在迭代中导致ConcurrentModificationException线程)但也慢(为什么一旦足够就反复取出一个锁)?

当然,即使你不需要,它也有锁定的开销。

基本上,在大多数情况下,这是一种非常有缺陷的同步方法。 As先生布赖恩亨克pointed出来,就可以使用电话,如Collections.synchronizedList装饰的集合 - 这VECTOR结合了“调整大小的数组”收集与执行的事实“同步每个操作”位是另一个例子设计不佳;装饰方法可以更清晰地分离顾虑。

至于'Stack等价物 - 我会先看看Deque /ArrayDeque


#2 热门回答(74 赞)

Vector是1.0的一部分 - 原始实现有两个缺点:

**1.命名:**vectors实际上只是可以作为数组访问的列表,因此它应该被称为ArrayList(它是Vector的Java 1.2 Collections替代品)。

**2.并发:**所有get()set()方法都是synchronized,所以你无法对同步进行细粒度控制。

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

来自API文档。

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


#3 热门回答(40 赞)

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