В моем пуле потоков есть фиксированное количество потоков. Эти потоки должны часто писать и читать из общего списка.
Итак, какая структура данных в java.util.concurrent
пакете (лучше List, должна быть без монитора) лучше всего в этом случае?
java
concurrency
象 嘉 道
источник
источник
List
.ConcurrentModificationException
Не может исходить от проблемы синхронизации; он также возникает, например, в цикле for для коллекции, когда вы пытаетесь удалить элемент из коллекции.Vector
?Ответы:
Только
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());
http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
источник
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:
источник
Если установлено достаточно, можно использовать ConcurrentSkipListSet . (Его реализация основана на ConcurrentSkipListMap, который реализует список пропуска .)
Ожидаемые средние временные затраты составляют log (n) для операций включения, добавления и удаления; метод размера не является операцией с постоянным временем.
источник