В моем пуле потоков есть фиксированное количество потоков. Эти потоки должны часто писать и читать из общего списка.
Итак, какая структура данных в java.util.concurrentпакете (лучше List, должна быть без монитора) лучше всего в этом случае?
В моем пуле потоков есть фиксированное количество потоков. Эти потоки должны часто писать и читать из общего списка.
Итак, какая структура данных в java.util.concurrentпакете (лучше List, должна быть без монитора) лучше всего в этом случае?
ConcurrentModificationExceptionНе может исходить от проблемы синхронизации; он также возникает, например, в цикле for для коллекции, когда вы пытаетесь удалить элемент из коллекции.
Vector?
Ответы:
лучше бы быть
List
Только List внедрение в java.util.concurrentэтом CopyOnWriteArrayList . Также есть возможность синхронизировать список, как упоминает Трэвис Уэбб.
Тем не менее, вы уверены, что вам это нужно List? Существует гораздо больше вариантов для одновременных Queues и Maps (и вы можете создавать Sets из Maps), и эти структуры, как правило, имеют наибольший смысл для многих типов вещей, которые вы хотите делать с общей структурой данных.
Для очередей у вас есть огромное количество вариантов, и какой из них наиболее подходит, зависит от того, как вам нужно его использовать:
CopyOnWriteArrayListимеет недостаток в том, что он очень дорог при записи (но дешев при чтении). Если вы выполняете много операций записи, вам лучше использовать синхронизированный список или очередь.
Любую коллекцию Java можно сделать потокобезопасной, например:
List newList = Collections.synchronizedList(oldList);
Или создать новый список потоковой безопасности:
List newList = Collections.synchronizedList(new ArrayList());
ConcurrentHashMapдаже несмотря на то, что есть Collections.synchronizedMapметод.
ConcurrentHashMap. Детали реализации синхронизации различны. использование synchronizedметодов в Collectionsосновном просто оборачивает класс в монитор Java. ConcurrentHashMapиспользует более умные функции параллелизма.
Если размер списка фиксирован, вы можете использовать AtomicReferenceArray . Это позволит вам выполнять индексированные обновления слота. При необходимости вы можете написать представление списка.
ConcurrentLinkedQueueиспользует очередь без блокировок (на основе более новой инструкции CAS ).
Listинтерфейс.
List.set(int index, Object element)с ConcurrentLinkedQueue?
Listспецифических методов либо не будут реализованы с использованием Queue(например, добавить / установить по определенному индексу), либо могут быть реализованы, но будут неэффективными (получить из индекса). Так что я не думаю, что вы действительно можете обернуть это. Тем не менее, я думаю, что предложение о создании файла - Queueэто нормально, поскольку ОП на самом деле не объяснил, зачем им нужен List.
Возможно, вам стоит взглянуть на ConcurrentDoublyLinkedList, написанный Дугом Ли на основе «Практического двусвязного списка без блокировок» Пола Мартина. Он не реализует интерфейс java.util.List, но предлагает большинство методов, которые вы бы использовали в List.
Согласно javadoc:
Параллельная реализация связанного списка Deque (двусторонняя очередь). Одновременные операции вставки, удаления и доступа безопасно выполняются в нескольких потоках. Итераторы слабо согласованы , возвращая элементы, отражающие состояние двухсторонней очереди в какой-то момент во время или после создания итератора. Они не генерируют исключение ConcurrentModificationException и могут выполняться одновременно с другими операциями.
Если установлено достаточно, можно использовать ConcurrentSkipListSet . (Его реализация основана на ConcurrentSkipListMap, который реализует список пропуска .)
Ожидаемые средние временные затраты составляют log (n) для операций включения, добавления и удаления; метод размера не является операцией с постоянным временем.
List.