Один из мемов, который вызывает стресс при разработке Java, - это всегда использовать ArrayList вместо Vector. Vector устарел. Это может быть правдой, но преимущество Vector и Hashtable в том, что они синхронизированы.
Я работаю с сильно ориентированным на параллелизм приложением, не будет ли пользы от использования синхронизируемых объектов, таких как Vector? Кажется, у них есть свое место?
В последней версии Java 6 с Netbeans утверждается, что Vector устарел ... Должно быть, это было объявлено где-то еще некоторое время назад, потому что у меня есть заметки за несколько месяцев о необходимости найти ему замену и проблемы с некоторыми не- устаревшие классы все еще нуждаются в этом.




Проблема с Vector и Hashtable в том, что они синхронизируются только локально. Они не будут ломаться (как в случае поврежденных данных) в параллельном приложении, однако из-за локальной синхронизации (например, get синхронизируется, но только до тех пор, пока get не вернется), вы все равно захотите выполнить свою собственную синхронизацию в таких ситуациях. как итерация по содержанию. Теперь даже вашему методу put требуется дополнительная синхронизация для взаимодействия с синхронизацией итераций, и вы получаете ситуацию, когда ваша Hashtable / Vector синхронизируется дважды.
По ошибке удалил свой комментарий. Вы ошибаетесь, что put () требует дополнительной синхронизации; итератор () будет просто синхронизироваться с самим вектором, который выполняет мьютексы со всей синхронизацией в векторе. В этом они идентичны Collections.synchronizedList ().
Если вы используете свой итератор в цикле for, содержимое цикла for не будет синхронизироваться, и ваш итератор, вероятно, вызовет исключение одновременной модификации, если кто-то использует put между 'next'. Следовательно, вам нужна дополнительная синхронизация (конечно, есть и другие варианты).
Да, синхронизируется по циклу, как описано в документации по коллекциям. Но вам не нужна дополнительная синхронизация между вашими путями и другими доступами, чтобы «сотрудничать» с итерацией, как вы это оговорили.
Ах да, я понимаю, что вы имеете в виду, вы, конечно, правы. Думаю, я немного поспешил выразить тот факт, что вам, вероятно, понадобится отдельная схема синхронизации, не связанная с одним массивом / картой, и поэтому внутренняя синхронизация будет чистыми накладными расходами.
Если вам нужен синхронизированный ArrayList или HashMap, вы можете их обернуть.
List list = Collections.synchronizedList(new ArrayList(...));
Map m = Collections.synchronizedMap(new HashMap(...));
Лично я считаю, что "синхронизированные" методы в этих коллекциях не очень полезны в тяжелом многопоточном коде. Есть несколько более новых коллекций, которые помогают намного больше, но в основном я обнаруживаю, что создаю свои собственные синхронизирующие объекты и синхронизирую их вокруг них или использую новые блокировки в java.util.concurrent
У синхронизации есть свое место, но это не единственное различие между Vector и ArrayList. Vector увеличивает свой внутренний массив хранения на фиксированную величину каждый раз, когда он превышает свою емкость, в то время как ArrayList увеличивает его на фиксированный коэффициент, что обычно является гораздо лучшим подходом (поскольку он дает амортизированная стоимость O (1) для добавления элемента).
Также обратите внимание, что Collections.synchronizedList() можно использовать для создания синхронизированного представления в любой реализации List, поэтому вам не нужно быть привязанным к характеристикам Vector (например, вам может понадобиться синхронизированный LinkedList).
Не совсем. Если вы не установите capacityIncrement для вектора, по умолчанию он будет удваивать свой размер, когда потребуется дополнительная емкость.
Похоже, я забыл об этом!
Вы можете использовать статические методы коллекций для преобразования списка или карты в синхронизированную версию: http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
Обычно вам нужно заблокировать больше, чем отдельный вызов списка или карты.
Мне кажется, что единственные случаи, когда вам потребуется, чтобы сама коллекция была потокобезопасной, это:
Все это, вероятно, плохие идеи с точки зрения дизайна.
Лучшим подходом было бы сделать саму коллекцию частной или защищенной и получить к ней доступ с помощью синхронизированных методов. В случае статического члена, если вам нужно это сделать, синглтон будет лучшим способом.
ConcurrentHashMap - это намного быстрее, чем Hashtable. Это одновременный, а не просто синхронизировано. Он допускает сразу несколько читателей / писателей.
Однако такого «параллельного» списка массивов не существует. В зависимости от ваших потребностей, CopyOnWriteArrayList может быть или не быть тем, что вам нужно.
Vector еще не объявлен устаревшим.