Как мне создать параллельный экземпляр List, в котором я могу получить доступ к элементам по индексу? Есть ли в JDK какие-либо классы или заводские методы, которые я могу использовать?
CopyOnWriteArrayList является ориентированным на многопотоковое исполнение вариантом ArrayList, в котором все изменчивые операции (добавляют, устанавливают, и так далее) реализованы путем создания новой копии основного массива.
CopyOnWriteArrayList является параллельной альтернативой для синхронизируемого интерфейса List реализаций Списка и его частью java.util.concurrent packageand, это - ориентированный на многопотоковое исполнение набор.
public class CopyOnWriteArrayList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
CopyOnWriteArrayList отказоустойчив и не бросает ConcurrentModificationException, когда базовый CopyOnWriteArrayList изменяется во время Итеративного использования отдельная копия ArrayList.
Это является обычно слишком дорогостоящим, потому что массив копии включил каждую операцию обновления будет создана, клонированная копия. CopyOnWriteArrayList является лучшим выбором только для частой операции чтения.
/**
* Returns a shallow copy of this list. (The elements themselves
* are not copied.)
*
* @return a clone of this list
*/
public Object clone() {
try {
@SuppressWarnings("unchecked")
CopyOnWriteArrayList<E> clone =
(CopyOnWriteArrayList<E>) super.clone();
clone.resetLock();
return clone;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
У Вас есть эти опции:
Collections.synchronizedList()
: можно перенести любой List
реализация (ArrayList
, LinkedList
или сторонний список). Доступ к каждому методу (чтение и запись) будет защищен с помощью synchronized
. При использовании iterator()
или улучшенный для цикла, необходимо вручную синхронизироваться; при итерации другие потоки полностью заблокированы даже от чтения.
CopyOnWriteArrayList
: дорого изменить, но свободный от блокировок для чтения. Итераторы никогда не бросают ConcurrentModificationException
, они возвращают снимок списка во время создания итератора, даже если список изменяется другим потоком при итерации. Полезный для нечасто обновляемых списков.
Vector
: очень как synchronizedList
, но повторение синхронизируется также. Однако итераторы могут бросить ConcurrentModificationException
, если вектор изменяется другим потоком.
Другие опции:
Collections.unmodifiableList()
: свободный от блокировок, ориентированный на многопотоковое исполнение, но немодифицируемый Queue
или Deque
могла бы быть альтернатива, если Вы только добавляете/удаляете в концах списка и выполняете итерации списка. Нет никакого индексного доступа и никакого добавления/удаления в произвольных местах. У них есть несколько параллельных реализаций с лучшей производительностью и лучшим параллельным доступом, но это выходит за рамки этого вопроса.