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

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

Не используется ли его использование при работе с concurrency?

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

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

615
06 сент. '09 в 21:04
источник поделиться
5 ответов

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

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

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

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

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

605
06 сент. '09 в 21:07
источник

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

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

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

Между ArrayList и Vector нет большой разницы, но вы должны использовать ArrayList.

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

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

74
06 сент. '09 в 21:12
источник

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

40
06 сент. '09 в 23:53
источник

Вы можете использовать метод synchronizedCollection/List на java.util.Collection, чтобы получить потокобезопасную коллекцию из небезобезопасного.

14
06 сент. '09 в 21:07
источник

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

4
13 февр. '16 в 0:04
источник

Посмотрите другие вопросы по меткам или Задайте вопрос