为什么 Java Vector(和 Stack)类被认为已过时或已弃用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1386275/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is Java Vector (and Stack) class considered obsolete or deprecated?
提问by fjsj
Why is Java Vector considered a legacy class, obsolete or deprecated?
为什么 Java Vector 被视为遗留类、已过时或已弃用?
Isn't its use valid when working with concurrency?
使用并发时它的使用是否有效?
And if I don't want to manually synchronize objects and just want to use a thread-safe collection without needing to make fresh copies of the underlying array (as CopyOnWriteArrayList
does), then is it fine to use Vector
?
如果我不想手动同步对象而只想使用线程安全集合而不需要制作底层数组的新副本(就像CopyOnWriteArrayList
那样),那么可以使用Vector
吗?
What about Stack
, which is a subclass of Vector
, what should I use instead of it?
怎么样Stack
,它是 的子类Vector
,我应该用什么来代替它?
采纳答案by Jon Skeet
Vector
synchronizes on each individual operation. That's almost never what you want to do.
Vector
在每个单独的操作上同步。这几乎从来都不是你想做的。
Generally you want to synchronize a whole sequenceof operations. Synchronizing individual operations is both less safe (if you iterate over a Vector
, for instance, you still need to take out a lock to avoid anyone else changing the collection at the same time, which would cause a ConcurrentModificationException
in the iterating thread) but also slower (why take out a lock repeatedly when once will be enough)?
通常,您希望同步整个操作序列。同步单个操作既不太安全(Vector
例如,如果您迭代 a ,您仍然需要取出锁以避免其他人同时更改集合,这会导致ConcurrentModificationException
迭代线程中的 a )而且速度较慢(为什么一次就足够了,为什么要反复取出锁)?
Of course, it also has the overhead of locking even when you don't need to.
当然,即使您不需要,它也有锁定的开销。
Basically, it's a very flawed approach to synchronization in most situations. As Mr Brian Henkpointed out, you can decorate a collection using the calls such as Collections.synchronizedList
- the fact that Vector
combines both the "resized array" collection implementation with the "synchronize every operation" bit is another example of poor design; the decoration approach gives cleaner separation of concerns.
基本上,在大多数情况下,这是一种非常有缺陷的同步方法。正如Brian Henk 先生指出的那样,您可以使用以下调用来装饰集合Collections.synchronizedList
-Vector
将“调整大小的数组”集合实现与“同步每个操作”位相结合的事实是另一个糟糕设计的例子;装饰方法提供了更清晰的关注点分离。
As for a Stack
equivalent - I'd look at Deque
/ArrayDeque
to start with.
至于Stack
等价物 - 我会先看Deque
/ ArrayDeque
。
回答by Brian Henk
You can use the synchronizedCollection/Listmethod in java.util.Collection
to get a thread-safe collection from a non-thread-safe one.
您可以使用synchronizedCollection/List方法java.util.Collection
从非线程安全集合中获取线程安全集合。
回答by Justin
Vector was part of 1.0 -- the original implementation had two drawbacks:
Vector 是 1.0 的一部分——最初的实现有两个缺点:
1. Naming:vectors are really just lists which can be accessed as arrays, so it should have been called ArrayList
(which is the Java 1.2 Collections replacement for Vector
).
1. 命名:向量实际上只是可以作为数组访问的列表,因此应该调用它ArrayList
(这是 Java 1.2 Collections 的替代品Vector
)。
2. Concurrency:All of the get()
, set()
methods are synchronized
, so you can't have fine grained control over synchronization.
2. 并发:所有的get()
,set()
方法都是synchronized
,所以你不能对同步进行细粒度的控制。
There is not much difference between ArrayList
and Vector
, but you should use ArrayList
.
ArrayList
和之间没有太大区别Vector
,但您应该使用ArrayList
.
From the API doc.
来自 API 文档。
As of the Java 2 platform v1.2, this class was retrofitted to implement the List interface, making it a member of the Java Collections Framework. Unlike the new collection implementations, Vector is synchronized.
从 Java 2 平台 v1.2 开始,该类经过改造以实现 List 接口,使其成为 Java Collections Framework 的成员。与新的集合实现不同,Vector 是同步的。
回答by Yishai
Besides the already stated answers about using Vector, Vector also has a bunch of methods around enumeration and element retrieval which are different than the List interface, and developers (especially those who learned Java before 1.2) can tend to use them if they are in the code. Although Enumerations are faster, they don't check if the collection was modified during iteration, which can cause issues, and given that Vector might be chosen for its syncronization - with the attendant access from multiple threads, this makes it a particularly pernicious problem. Usage of these methods also couples a lot of code to Vector, such that it won't be easy to replace it with a different List implementation.
除了已经说明的关于使用 Vector 的答案外,Vector 还有一堆枚举和元素检索方法,这些方法与 List 接口不同,开发人员(尤其是那些在 1.2 之前学习过 Java 的开发人员)如果在代码。尽管枚举速度更快,但它们不会检查集合是否在迭代期间被修改,这可能会导致问题,并且考虑到可能会选择 Vector 进行同步 - 伴随着来自多个线程的访问,这使其成为一个特别有害的问题。使用这些方法还会将大量代码耦合到 Vector,因此用不同的 List 实现替换它并不容易。
回答by 200_success
java.util.Stack
inherits the synchronization overhead of java.util.Vector
, which is usually not justified.
java.util.Stack
继承了 的同步开销java.util.Vector
,这通常是不合理的。
It inherits a lot more than that, though. The fact that java.util.Stack extends java.util.Vector
is a mistake in object-oriented design. Purists will note that it also offers a lot of methods beyond the operations traditionally associated with a stack (namely: push, pop, peek, size). It's also possible to do search
, elementAt
, setElementAt
, remove
, and many other random-access operations. It's basically up to the user to refrain from using the non-stack operations of Stack
.
不过,它继承的远不止这些。事实上,这java.util.Stack extends java.util.Vector
是面向对象设计中的一个错误。纯粹主义者会注意到,除了传统上与堆栈相关的操作(即:push、pop、peek、size)之外,它还提供了许多方法。它也可以做到search
,elementAt
,setElementAt
,remove
,和其他许多随机存取操作。基本上由用户决定不使用Stack
.
For these performance and OOP design reasons, the JavaDoc for java.util.Stack
recommends ArrayDeque
as the natural replacement. (A deque is more than a stack, but at least it's restricted to manipulating the two ends, rather than offering random access to everything.)
由于这些性能和 OOP 设计原因,JavaDoc forjava.util.Stack
推荐ArrayDeque
作为自然的替代品。(双端队列不仅仅是一个堆栈,但至少它仅限于操作两端,而不是提供对所有内容的随机访问。)