Выбор лучшего concurrency списка в Java
Мой пул потоков имеет фиксированное количество потоков. Эти потоки часто должны писать и читать из общего списка.
Итак, какая структура данных (лучше быть списком, должна быть без монитора) в пакете java.util.concurrent
лучше всего в этом случае?
Ответы
Ответ 1
лучше List
Единственная реализация List
в java.util.concurrent
- CopyOnWriteArrayList. Также существует опция синхронизированного списка, как упоминает Travis Webb.
Тем не менее, вы уверены, что вам нужно быть List
? Есть гораздо больше возможностей для параллельных Queue
и Map
(и вы можете сделать Set
от Map
s), и эти структуры, как правило, имеют наибольший смысл для многих типов вещей, которые вы хотите сделать с общей структурой данных.
Для очередей у вас есть огромное количество опций, и это самое подходящее зависит от того, как вам нужно его использовать:
Ответ 2
Любая коллекция Java может быть сделана так, чтобы она была безопасной:
List newList = Collections.synchronizedList(oldList);
Или создать совершенно новый потокобезопасный список:
List newList = Collections.synchronizedList(new ArrayList());
http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
Ответ 3
Если размер списка фиксирован, вы можете использовать AtomicReferenceArray. Это позволит вам выполнять индексированные обновления в слот. Вы можете написать представление списка, если это необходимо.
Ответ 4
Возможно, вам захочется взглянуть на ConcurrentDoublyLinkedList, написанный Дугом Ли на основе Пола Мартина "Практический беззаботный двойной список". Он не реализует интерфейс java.util.List, но предлагает большинство методов, которые вы использовали бы в списке.
Согласно javadoc:
Реализация параллельного связанного списка Deque (двухсторонняя очередь). Параллельные операции вставки, удаления и доступа выполняются безопасно для нескольких потоков. Итераторы слабо согласованы, возвращая элементы, отражающие состояние дека в какой-то момент на или после создания итератора. Они не бросают ConcurrentModificationException и могут продолжаться одновременно с другими операциями.
Ответ 5
ConcurrentLinkedQueue
использует незаблокированную очередь (основанную на новой Инструкция CAS).
Ответ 6
Если набор достаточен, ConcurrentSkipListSet может быть использован.
(Его реализация основана на ConcurrentSkipListMap, который реализует список пропуска.)
Ожидаемая средняя временная стоимость - log (n) для операций сложениями, добавлениями и удалениями; метод размера не является операцией с постоянным временем.