Почему класс Java Vector (и Stack) считается устаревшим или устаревшим?


Почему Ява вектор считается устаревшей класса, устаревших?

разве его использование не допустимо при работе с параллелизмом?

и если я не хочу вручную синхронизировать объекты и просто хочу использовать потокобезопасную коллекцию без необходимости делать свежие копии базового массива (как CopyOnWriteArrayList делает), то это нормально, чтобы использовать Vector?

А как же Stack, который является подклассом Vector, что я должен использовать вместо него?

5 617

5 ответов:

Vector синхронизируется на каждой отдельной операции. Это почти никогда не то, что вы хотите сделать.

как правило, вы хотите синхронизировать вся последовательность операций. Синхронизация отдельных операций является менее безопасным (если вы повторяете над Vector, например, вам все равно нужно вынуть блокировку, чтобы никто не менял коллекцию одновременно, что вызвало бы ConcurrentModificationException в итерационном потоке) , но и медленнее (зачем вынимать блокировку неоднократно, когда одного раза будет достаточно)?

конечно, он также имеет накладные расходы на блокировку, даже если вам это не нужно.

в принципе, это очень ошибочный подход к синхронизации в большинстве ситуаций. Как Мистер Брайан Хенк указал, вы можете украсить коллекцию с помощью вызовов, таких как Collections.synchronizedList - дело в том, что Vector объединяет как реализацию коллекции" измененный массив "с битом" синхронизировать каждую операцию", так и другой пример плохого дизайна; подход к украшению дает более чистое разделение проблем.

Что касается Stack эквивалент-я бы посмотрел на Deque/ArrayDeque для начала.

вектор был частью 1.0-оригинальная реализация имел два недостатка:

1. Именование: векторы на самом деле просто списки, которые могут быть доступны в виде массивов, поэтому он должен был называться ArrayList (что является заменой коллекций Java 1.2 для Vector).

2. Параллелизм: все get(),set() методы synchronized, так что вы не можете иметь отличный контроль над синхронизацией.

там не так много разница между ArrayList и Vector, но вы должны использовать ArrayList.

из документа API.

начиная с платформы Java 2 v1. 2, это класс был модернизирован для реализации Интерфейс списка, делая его членом платформы наборов Java. В отличие от реализация новой коллекции, Вектор синхронизации.

помимо уже заявленных ответов об использовании Vector, Vector также имеет множество методов вокруг перечисления и извлечения элементов, которые отличаются от интерфейса списка, и разработчики (особенно те, кто изучил Java до 1.2) могут использовать их, если они находятся в коде. Хотя перечисления выполняются быстрее, они не проверяют, была ли коллекция изменена во время итерации, что может вызвать проблемы, и учитывая, что вектор может быть выбран для его синхронизации - с помощью сопутствующий доступ из нескольких потоков, это делает его особенно пагубной проблемой. Использование этих методов также связывает много кода с вектором, так что будет нелегко заменить его другой реализацией списка.

можно использовать synchronizedCollection / List метод on 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 как естественная замена. (Дек-это больше, чем стек, но, по крайней мере, он ограничен манипулированием двумя концами, а не предлагает случайный доступ ко всему.)