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