Как я могу создать параллельный экземпляр List, где я могу получить доступ к элементам по индексу? Есть ли в JDK классы или фабричные методы, которые я могу использовать?
java
list
concurrency
AlikElzin-kilaka
источник
источник
List
какой оригинал специально говорит это требование, которое считается вандализмом. Модератор уже заблокировал вопрос из-за людей, которые жалуются на то, что ответы не отвечают на эту разрушенную версию вопроса.locked
/closed
/ Предыдущий комментарийОтветы:
В java.util.concurrent есть параллельная реализация списка . CopyOnWriteArrayList в частности.
источник
Если вы не заботитесь о доступе на основе индекса и просто хотите сохранить в List характеристики сохранения порядка вставки, вы можете рассмотреть java.util.concurrent.ConcurrentLinkedQueue . Поскольку он реализует Iterable, после добавления всех элементов вы можете перебирать содержимое, используя расширенный синтаксис for:
источник
:
) называется foreach: docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.htmlВы можете очень хорошо использовать Collections.synchronizedList (List), если все, что вам нужно, это простая синхронизация вызовов:
источник
synchronizedList
"синхронизирован", но не "параллелен". Одна фундаментальная проблема заключается в том, что многие операции List, основанные на индексах, сами по себе не являются атомарными и должны быть частью более широкой конструкции взаимного исключения.Vector
является более простым, чемCollections.synchronizedList(new ArrayList<Object>())
.Поскольку процесс получения позиции и получения элемента из данной позиции, естественно, требует некоторой блокировки (вы не можете иметь в списке структурные изменения между этими двумя операциями).
Сама идея параллельной коллекции состоит в том, что каждая отдельная операция является атомарной и может выполняться без явной блокировки / синхронизации.
Следовательно, получение элемента в позиции
n
из заданнойList
в качестве атомарной операции не имеет особого смысла в ситуации, когда ожидается одновременный доступ.источник
У вас есть эти варианты:
Collections.synchronizedList()
Вы можете обернуть любуюList
реализацию (ArrayList
,LinkedList
или список третьих сторон). Доступ к каждому методу (чтение и запись) будет защищен с помощьюsynchronized
. При использованииiterator()
или улучшении цикла for вы должны вручную синхронизироваться; во время итерации другие потоки полностью блокируются даже для чтения. Вы также можете синхронизировать отдельно для каждогоhasNext
иnext
звонков, но тогдаConcurrentModificationException
это возможно.CopyOnWriteArrayList
: это дорого модифицировать, но читать без ожидания. Итераторы никогда не генерируютConcurrentModificationException
, они возвращают снимок списка в момент создания итератора, даже если список изменяется другим потоком во время итерации. Полезно для нечасто обновляемых списков. Массовые операции, такие какaddAll
, предпочтительнее для обновлений - внутренний массив копируется реже.Vector
: очень нравитсяsynchronizedList
, но итерация тоже синхронизирована. Однако итераторы могут выдаватьConcurrentModificationException
, если вектор модифицируется другим потоком во время итерации.Другие варианты:
Collections.unmodifiableList()
: без блокировки, поточно-ориентированный, но не модифицируемыйQueue
илиDeque
может быть альтернативой, если вы добавляете / удаляете только в конце списка и повторяете список. Нет доступа по индексу и нет добавления / удаления в произвольных местах. У них есть несколько одновременных реализаций с лучшей производительностью и лучшим параллельным доступом, но это выходит за рамки этого вопроса. Вы также можете взглянуть на JCTools , они содержат более производительные реализации очереди, предназначенные для одного потребителя или одного производителя.источник
CopyOnWriteArrayList - это параллельная альтернатива синхронизированного List, реализующего интерфейс List и его часть пакета java.util.concurrent и его потокобезопасную коллекцию.
CopyOnWriteArrayList является отказоустойчивым и не генерирует исключение ConcurrentModificationException, когда базовый CopyOnWriteArrayList изменяется во время итерации, используя отдельную копию ArrayList.
Это обычно слишком дорого, потому что массив копий, включающий каждую операцию обновления, будет клонированной копией. CopyOnWriteArrayList - лучший выбор только для частых операций чтения.
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/CopyOnWriteArrayList.html
https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/CopyOnWriteArrayList.html
источник