В моем пуле потоков есть фиксированное количество потоков. Эти потоки должны часто писать и читать из общего списка.
Итак, какая структура данных в java.util.concurrent
пакете (лучше List, должна быть без монитора) лучше всего в этом случае?
В моем пуле потоков есть фиксированное количество потоков. Эти потоки должны часто писать и читать из общего списка.
Итак, какая структура данных в java.util.concurrent
пакете (лучше List, должна быть без монитора) лучше всего в этом случае?
ConcurrentModificationException
Не может исходить от проблемы синхронизации; он также возникает, например, в цикле for для коллекции, когда вы пытаетесь удалить элемент из коллекции.
Vector
?
Ответы:
лучше бы быть
List
Только List
внедрение в java.util.concurrent
этом CopyOnWriteArrayList . Также есть возможность синхронизировать список, как упоминает Трэвис Уэбб.
Тем не менее, вы уверены, что вам это нужно List
? Существует гораздо больше вариантов для одновременных Queue
s и Map
s (и вы можете создавать Set
s из Map
s), и эти структуры, как правило, имеют наибольший смысл для многих типов вещей, которые вы хотите делать с общей структурой данных.
Для очередей у вас есть огромное количество вариантов, и какой из них наиболее подходит, зависит от того, как вам нужно его использовать:
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
.