Answers:
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是同步的。
ArrayList
,LinkedList
等等,所有这些都实现这个接口List
,所以如果你想使用的List
方法,而无需知道底层的实现实际上是你可以采取一个List
作为参数传递给方法,等等。这同样适用于工作的执行Map
等等。同时,C ++确实有一个std::array
类,该类只是基于模板的C样式静态长度数组的替代。
您可以在其中使用syncedCollection / List方法java.util.Collection
从非线程安全的集合中获取线程安全的集合。
java.util.Stack
继承的同步开销java.util.Vector
,通常是不合理的。
但是,它继承的更多。这java.util.Stack extends java.util.Vector
是面向对象设计中的错误。纯粹主义者将注意到,除了传统上与堆栈相关的操作(即:推入,弹出,窥视,大小)之外,它还提供了许多方法。它也可以做到search
,elementAt
,setElementAt
,remove
,和其他许多随机存取操作。基本上,用户应避免使用的非堆栈操作Stack
。
由于这些性能和OOP设计原因,推荐使用JavaDocjava.util.Stack
ArrayDeque
作为自然替代品。(双端队列不仅是堆栈,但至少限于操作两端,而不是提供对所有内容的随机访问。)