Dlaczego Java Vector jest uważana za klasę starszą, przestarzałą lub przestarzałą?
Czy jego użycie nie jest prawidłowe podczas pracy z współbieżnością?
A jeśli nie chcę ręcznie synchronizować obiektów i chcę po prostu użyć kolekcji bezpiecznej dla wątków bez konieczności tworzenia nowych kopii podstawowej tablicy (jak to CopyOnWriteArrayList
ma miejsce), to czy można z niej korzystać Vector
?
A Stack
co z podklasą Vector
, czego powinienem użyć zamiast tego?
Odpowiedzi:
Vector
synchronizuje każdą operację. Prawie nigdy nie chcesz tego robić.Zasadniczo chcesz zsynchronizować całą sekwencję operacji. Synchronizacja poszczególnych operacji jest zarówno mniej bezpieczna (jeśli wykonujesz iterację
Vector
, na przykład, nadal musisz wyjąć blokadę, aby nikt inny nie zmieniał kolekcji w tym samym czasie, co spowodowałobyConcurrentModificationException
iterację w wątku iteracyjnym), ale także wolniej ( po co wielokrotnie wyjmować blokadę, kiedy raz będzie to wystarczające)?Oczywiście ma również narzut związany z blokowaniem, nawet gdy nie jest to konieczne.
Zasadniczo jest to bardzo wadliwe podejście do synchronizacji w większości sytuacji. Jak zauważył Brian Henk , można udekorować kolekcję za pomocą wywołań takich jak:
Collections.synchronizedList
- fakt, któryVector
łączy zarówno implementację kolekcji „zmienionej tablicy” z bitem „synchronizuj każdą operację”, jest kolejnym przykładem złego projektu; podejście do dekoracji zapewnia wyraźniejsze oddzielenie problemów.Jeśli chodzi o
Stack
odpowiednik - chciałbym zacząć odDeque
/ArrayDeque
zacząć.źródło
Vector był częścią 1.0 - oryginalna implementacja miała dwie wady:
1. Nazewnictwo: wektory są tak naprawdę tylko listami, do których można uzyskać dostęp jako tablice, więc należy je nazwać
ArrayList
(w zamian za kolekcje Java 1.2Vector
).2. współbieżności: Wszystko z
get()
,set()
metody sąsynchronized
, więc nie można się drobnoziarnisty kontrolę nad synchronizacją.Nie ma dużej różnicy między
ArrayList
iVector
, ale powinieneś użyćArrayList
.Z dokumentu API
źródło
ArrayList
,LinkedList
itp, z których wszystkie implementują interfejsList
, więc jeśli chcesz korzystać zList
metody bez konieczności wiedzieć, co podstawowa realizacja rzeczywistości można po prostu wziąćList
jako parametr do metody, itp To samo dotyczy realizatorówMap
i tak dalej. Tymczasem C ++ mastd::array
klasę, która jest po prostu szablonowym zamiennikiem macierzy długości statycznej typu C.Oprócz już podanych odpowiedzi na temat korzystania z Vector, Vector ma również szereg metod dotyczących wyliczania i pobierania elementów, które są inne niż interfejs List, a programiści (szczególnie ci, którzy nauczyli się Javy przed 1.2) mogą z nich korzystać, jeśli są w kod. Chociaż wyliczenia są szybsze, nie sprawdzają, czy kolekcja została zmodyfikowana podczas iteracji, co może powodować problemy, a biorąc pod uwagę, że Vector może zostać wybrany do jego synchronizacji - z dostępnym dostępem z wielu wątków, sprawia to, że jest to szczególnie szkodliwy problem. Wykorzystanie tych metod powoduje również sprzężenie dużej ilości kodu z Vectorem, dzięki czemu nie będzie łatwo zastąpić go inną implementacją List.
źródło
Możesz użyć metody synchronizedCollection / List ,
java.util.Collection
aby uzyskać kolekcję bezpieczną dla wątków z kolekcji innej niż bezpieczna dla wątków.źródło
java.util.Stack
dziedziczy narzut związany z synchronizacjąjava.util.Vector
, co zwykle nie jest uzasadnione.Jednak dziedziczy o wiele więcej. To
java.util.Stack extends java.util.Vector
błąd w projektowaniu obiektowym. Puryści zauważą, że oferuje również wiele metod poza operacjami tradycyjnie związanymi ze stosem (a mianowicie: push, pop, peek, size). Jest to również możliwe do zrobieniasearch
,elementAt
,setElementAt
,remove
, oraz wiele innych operacji o dostępie swobodnym. Zasadniczo to użytkownik nie powinien korzystać z operacji bez stosuStack
.Z tych powodów wydajności i projektowania OOP JavaDoc
java.util.Stack
polecaArrayDeque
jako naturalny zamiennik. (Deque to więcej niż stos, ale przynajmniej ogranicza się do manipulowania dwoma końcami, zamiast oferować losowy dostęp do wszystkiego.)źródło