Почему класс Java Vector (и Stack) считается устаревшим или устаревшим?
Почему Java Vector считается устаревшим классом, устаревшим или устаревшим?
Разве его использование не допустимо при работе с параллелизмом?
И если я не хочу вручную синхронизировать объекты и просто хочу использовать потокобезопасную коллекцию без необходимости делать свежие копии базового массива (как CopyOnWriteArrayList
делает), то можно ли использовать Vector
?
Как насчет Stack
, который является подклассом Vector
что я должен использовать вместо этого?
5 ответов
Vector
синхронизируется на каждой отдельной операции. Это почти никогда не то, что вы хотите сделать.
Как правило, вы хотите синхронизировать всю последовательность операций. Синхронизация отдельных операций менее безопасна (если вы выполняете Vector
Например, вам все еще нужно снять блокировку, чтобы никто не мог изменить коллекцию одновременно, что могло бы вызвать ConcurrentModificationException
в итерационном потоке), но также и медленнее (зачем снимать блокировку несколько раз, когда этого будет достаточно)?
Конечно, он также имеет накладные расходы на блокировку, даже когда вам это не нужно.
По сути, это очень некорректный подход к синхронизации в большинстве ситуаций. Как отметил г-н Брайан Хенк, вы можете украсить коллекцию, используя такие вызовы, как Collections.synchronizedList
- дело в том, что Vector
объединение реализации коллекции "массив с измененным размером" и бита "синхронизировать каждую операцию" - еще один пример плохого дизайна; декоративный подход дает более четкое разделение проблем.
Что касается Stack
эквивалент - я бы посмотрел на Deque
/ ArrayDeque
начать с.
Vector был частью 1.0 - оригинальная реализация имела два недостатка:
1. Наименование: векторы на самом деле представляют собой просто списки, к которым можно обращаться как к массивам, поэтому их следует называть ArrayList
(что является заменой коллекций Java 1.2 для Vector
).
2. Параллелизм: все get()
, set()
методы synchronized
, так что вы не можете иметь мелкозернистый контроль над синхронизацией.
Там нет большой разницы между ArrayList
а также Vector
, но вы должны использовать ArrayList
,
Из API док.
Что касается платформы Java 2 v1.2, этот класс был модифицирован для реализации интерфейса List, что сделало его членом Java Collections Framework. В отличие от новых реализаций коллекции, Vector синхронизирован.
Помимо уже заявленных ответов об использовании Vector, в Vector также есть несколько методов для перечисления и извлечения элементов, которые отличаются от интерфейса List, и разработчики (особенно те, кто изучал Java до 1.2) могут использовать их, если они находятся в код. Несмотря на то, что перечисления выполняются быстрее, они не проверяют, была ли коллекция изменена во время итерации, что может вызвать проблемы, и учитывая, что Vector может быть выбран для его синхронизации - с помощью сопутствующего доступа из нескольких потоков, это делает ее особенно пагубной проблемой. Использование этих методов также связывает большую часть кода с Vector, поэтому заменить его другой реализацией List будет нелегко.
Вы можете использовать метод synchronizedCollection/List на java.util.Collection
получить потокобезопасную коллекцию из не поточно-безопасной.
java.util.Stack
наследует издержки синхронизации java.util.Vector
, что обычно не оправдано.
Хотя он наследует намного больше, чем это. Дело в том, что java.util.Stack extends java.util.Vector
это ошибка в объектно-ориентированном дизайне. Пуристы заметят, что он также предлагает множество методов помимо операций, традиционно связанных со стеком (а именно: push, pop, peek, size). Также возможно сделать search
, elementAt
, setElementAt
, remove
и многие другие операции произвольного доступа. Это в основном зависит от пользователя, чтобы воздерживаться от использования не-стек операций Stack
,
По этим причинам производительности и дизайна ООП JavaDoc для java.util.Stack
рекомендует ArrayDeque
как естественная замена. (Deque - это больше, чем стек, но, по крайней мере, он ограничен манипулированием двумя концами, а не предлагает произвольный доступ ко всему.)