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

发布于 2024-08-04 10:32:46 字数 234 浏览 12 评论 0 原文

为什么 Java Vector 被视为遗留类、已过时或已弃用?

在处理并发时它的使用不是有效的吗?

如果我不想手动同步对象,只想使用线程安全集合,而不需要制作底层数组的新副本(如 CopyOnWriteArrayList 所做的那样),那么可以使用向量

Stack 怎么样,它是 Vector 的子类,我应该用什么来代替它?

Why is Java Vector considered a legacy class, obsolete or deprecated?

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?

What about Stack, which is a subclass of Vector, what should I use instead of it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

醉殇 2024-08-11 10:32:46

Vector 同步每个单独的操作。这几乎从来都不是你想做的事。

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

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

基本上,在大多数情况下,这是一种非常有缺陷的同步方法。正如 Brian Henk 先生指出的那样,您可以使用诸如 Collections.synchronizedList - Vector 结合了“调整大小的数组”集合实现与“同步每个操作”位是糟糕设计的另一个例子;装饰方法可以更清晰地分离关注点。

至于 Stack 等效项 - 我会首先查看 Deque/ArrayDeque

Vector synchronizes on each individual operation. That's almost never what you want to do.

Generally you want to synchronize a whole sequence of 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)?

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 Henk pointed 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.

As for a Stack equivalent - I'd look at Deque/ArrayDeque to start with.

玻璃人 2024-08-11 10:32:46

Vector 是 1.0 的一部分——最初的实现有两个缺点:

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

2.并发:所有get()set()方法都是同步,因此您无法进行细粒度控制过度同步。

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

来自 API 文档。

从 Java 2 平台 v1.2 开始,这
类被改造以实现
列表接口,使其成为
Java 集合框架。不像
新的集合实现,
矢量已同步。

Vector was part of 1.0 -- the original implementation had two drawbacks:

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).

2. Concurrency: All of the get(), set() methods are synchronized, so you can't have fine grained control over synchronization.

There is not much difference between ArrayList and Vector, but you should use ArrayList.

From the API doc.

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.

作死小能手 2024-08-11 10:32:46

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

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.

ㄖ落Θ余辉 2024-08-11 10:32:46

java.util.Stack 继承了 java.util.Vector 的同步开销,这通常是不合理的。

但它继承的远不止于此。 java.util.Stack 扩展了 java.util.Vector 是面向对象设计中的一个错误。纯粹主义者会注意到,它还提供了许多超出传统上与堆栈相关的操作的方法(即:push、pop、peek、size)。还可以执行 searchelementAtsetElementAtremove 和许多其他随机访问操作。基本上由用户决定是否避免使用 Stack 的非堆栈操作。

由于这些性能和 OOP 设计原因,JavaDoc for java.util.Stack 推荐 ArrayDeque 作为自然的替代品。 (双端队列不仅仅是一个堆栈,但至少它仅限于操作两端,而不是提供对所有内容的随机访问。)

java.util.Stack inherits the synchronization overhead of java.util.Vector, which is usually not justified.

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.

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.)

瑕疵 2024-08-11 10:32:46

您可以使用 java.util.Collection 中的 >synchronizedCollection/List 方法从非线程安全集合获取线程安全集合。

You can use the synchronizedCollection/List method in java.util.Collection to get a thread-safe collection from a non-thread-safe one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文