爲什麼Java Vector(和Stack)類被認爲已過時或已棄用?

本文翻譯自:Why is Java Vector (and Stack) class considered obsolete or deprecated?

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一個子類,應該用什麼而不是它呢?


#1樓

參考:https://stackoom.com/question/5odH/爲什麼Java-Vector-和Stack-類被認爲已過時或已棄用


#2樓

您可以使用java.util.Collection上的synchronizedCollection / List方法從非線程安全的集合java.util.Collection獲取線程安全集合。


#3樓

Vector synchronizes on each individual operation. Vector在每個單獨的操作上同步。 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)? 同步單個操作既不安全(例如,如果迭代Vector ,你仍然需要取出一個鎖以避免其他人同時更改集合,這會在迭代線程中導致ConcurrentModificationException )而且慢一點(爲什麼一旦足夠就反覆取出鎖)?

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; 正如Brian Henk先生指出的那樣,您可以使用Collections.synchronizedList等調用來裝飾集合 - Vector將“調整大小的數組”集合實現與“同步每個操作”位相結合,這是設計不佳的另一個例子; the decoration approach gives cleaner separation of concerns. 裝飾方法可以更清晰地分離顧慮。

As for a Stack equivalent - I'd look at Deque / ArrayDeque to start with. 至於Stack等價物 - 我會先看看Deque / ArrayDeque


#4樓

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 (它是Vector的Java 1.2 Collections替代品)。

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 . ArrayListVector之間沒有太大區別,但您應該使用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. 從Java 2平臺v1.2開始,這個類被改進以實現List接口,使其成爲Java Collections Framework的成員。 Unlike the new collection implementations, Vector is synchronized. 與新的集合實現不同,Vector是同步的。


#5樓

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. 除了已經陳述的關於使用Vector的答案之外,Vector還有許多關於枚舉和元素檢索的方法,這些方法與List接口不同,開發人員(特別是那些在1.2之前學習Java的人)可能傾向於使用它們,如果他們在碼。 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. 儘管枚舉速度更快,但它們不會檢查集合是否在迭代期間被修改,這可能會導致問題,並且考慮到可能會選擇Vector進行同步 - 通過多線程的話務員訪問,這使得它成爲一個特別有害的問題。 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,因此用不同的List實現替換它並不容易。


#6樓

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. java.util.Stack extends java.util.Vector這一事實在面向對象設計java.util.Stack extends java.util.Vector是一個錯誤。 Purists will note that it also offers a lot of methods beyond the operations traditionally associated with a stack (namely: push, pop, peek, size). 純粹主義者會注意到它除了傳統上與堆棧相關的操作之外還提供了許多方法(即:push,pop,peek,size)。 It's also possible to do search , elementAt , setElementAt , remove , and many other random-access operations. 它還可以執行searchelementAtsetElementAtremove和許多其他隨機訪問操作。 It's basically up to the user to refrain from using the non-stack operations of Stack . 基本上由用戶決定不使用Stack的非堆棧操作。

For these performance and OOP design reasons, the JavaDoc for java.util.Stack recommends ArrayDeque as the natural replacement. 出於這些性能和OOP設計的原因, java.util.StackJavaDoc建議將ArrayDeque作爲自然替代品。 (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.) (deque不僅僅是一個堆棧,但至少它僅限於操縱兩端,而不是隨機訪問所有內容。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章