Точные используемые операции должны определять, что используется.Однако, поскольку контейнер является в значительной степени абстрактным типом, напишите его так, чтобы он работал - надежно - затем профилируйте, обеспечьте функциональные требования, оптимизируйте по мере необходимости, бла-бла:)
Обычно,мое основное использование для "параллельной коллекции" - это очередь, которая используется для передачи объектов между потоками.В этом случае я начинаю с ConcurrentLinkedQueue , если не по какой-либо другой причине, кроме симпатии к алгоритму «без блокировки» (это не значит, что он будет быстрее: -).
ОбычноОчередь и / или LinkedList - это хорошая структура данных, которую нужно добавить в конец.В зависимости от обстоятельств, включая конкретные шаблоны использования, включая: конфликт потоков, количество удаленных элементов, порядок удаления элементов и т. Д. , «быстрое уничтожение» всего, кроме начала / конца может Быстрее выполнить с помощью clear
(часть AbstractQueue) и повторного добавления предметов - ConcurrentLinkedQueue позволяет осматривать / манипулировать хвостом и головы.Тем не менее, я хотел бы призвать «держать его проще», писать в «конкретный контракт интерфейса» и «просто использовать текущий подход», пока не будет убедительных доказательств того, что функциональное требование не выполнено.
Что касаетсяпроизводительность, это действительно зависит от конкретных характеристик структуры данных сценария использования / операций и реализации структуры данных.В некоторых случаях ArrayList может быть очень медленным, чем Vector, и это действительно задокументировано.Если это представление имеет значение, хотя, что-то звучит подозрительно.Статья на Java Best Practices - Vector против ArrayList против HashSet содержит хорошее чтение.Обратите также внимание на комментарии.
Edit: Помните, что "параллельная" структура данных обычно подразумевает только то, что одиночная операция (вызов метода) является атомарной(и, возможно, не все операции в нечетных случаях!).Для достижения требуемого уровня безопасности потока все еще может потребоваться реализовать синхронизацию с большой областью действия или другой подход.Таким образом, h.putIfAbsent(k,v)
(из ConcurrentHashMap) - это не то же самое , что и if (!h.containsKey(k)) { h.put(k, v); }
- как пример, проблема, подобная этой, относится к упомянутому подходу «очистить, а затем добавить»выше.
Счастливого кодирования.