Должен ли я использовать старую синхронизированную коллекцию Vector, ArrayList с синхронизированным доступом или Collections.synchronizedList или какое-либо другое решение для одновременного доступа?
Я не вижу своего вопроса ни в связанных вопросах, ни в моем поиске ( Сделать ваши коллекции безопасными для потоков? не совпадает).
В последнее время мне приходилось проводить своего рода модульные тесты в частях нашего приложения с графическим интерфейсом (в основном, с использованием API для создания фреймов, добавления объектов и т. Д.).
Поскольку эти операции вызываются намного быстрее, чем пользователем, обнаружен ряд проблем с методами, пытающимися получить доступ к ресурсам, которые еще не созданы или уже удалены.
Особая проблема, возникающая в EDT, возникла в результате обхода связанного списка представлений при изменении его в другом потоке (получение исключения ConcurrentModificationException среди других проблем).
Не спрашивайте меня, почему это был связанный список, а не простой список массивов (тем более, что у нас вообще 0 или 1 вид внутри ...), поэтому я взял более распространенный ArrayList в своем вопросе (так как он имеет старший двоюродный брат).
Во всяком случае, не очень знакомый с проблемами параллелизма, я посмотрел немного информации и подумал, что выбрать между старым (и, вероятно, устаревшим) Vector (который синхронизировал операции по дизайну), ArrayList с synchronized (myList) { }
вокруг критические разделы (операции добавления / удаления / обхода) или использование списка, возвращаемого Collections.synchronizedList (даже не уверен, как использовать последний).
Я, наконец, выбрал второй вариант, потому что еще одна ошибка проектирования заключалась в том, чтобы выставить объект (метод getViewList () ...) вместо предоставления механизмов для его использования.
Но каковы плюсы и минусы других подходов?
[РЕДАКТИРОВАТЬ] Здесь много хороших советов, трудно выбрать один. Я выберу более подробный и предоставляющий ссылки / пищу для размышлений ... :-) Мне тоже нравится Даррон.
Подведем итог:
- Как я и подозревал, Vector (и его злой близнец, возможно, и Hashtable) в значительной степени устарели, я видел людей, которые говорили, что его старый дизайн не так хорош, как новые коллекции, за исключением медленной синхронизации, вызванной даже в однопоточное окружение. Если мы сохраняем это, это происходит главным образом потому, что старые библиотеки (и части Java API) все еще используют его.
- В отличие от того, что я думал, Collections.synchronizedXxxx не более современны, чем Vector (они кажутся современными для Collections, т.е. Java 1.2!), И на самом деле не лучше. Хорошо знать. Короче говоря, я должен их избегать.
- Ручная синхронизация кажется хорошим решением в конце концов. Возможны проблемы с производительностью, но в моем случае это не критично: операции, выполняемые над действиями пользователя, небольшая коллекция, частое использование.
- Следует иметь в виду пакет java.util.concurrent, особенно методы CopyOnWrite.
Надеюсь, я правильно понял ...: -)