betacode

Руководство Java CopyOnWriteArrayList

  1. CopyOnWriteArrayList

1. CopyOnWriteArrayList

CopyOnWriteArrayList - это потокобезопасный вариант of ArrayList. Подобно ArrayList, CopyOnWriteArray, онуправляет массивом для хранения его элементов. Разница в том, что все мутативные операции, такие как add, set, remove, clear,... создают новую копию массива, которым он управляет.
public class CopyOnWriteArrayList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
Давайте посмотрим, что происходит при добавлении элемента в CopyOnWriteArrayList:
Стоимость использования CopyOnWriteArrayList очень высока, вам придется платить больше за ресурс и производительность. Однако CopyOnWriteArrayList пригодится, когда вы не можете или не хотите синхронизировать при обходе (traversal) элементов списка.
Для лучшего понимания рассмотрим ситуацию, когда два Thread используют один и тот же объект List. В то время как Thread-A обходит (traversal) элементы List, он замораживает действия вставки или обновления в List для целостности данных, но, очевидно, это влияет на действия Thread-B.
Когда вы создаете объект Iterator из CopyOnWriteArrayList, он помогает вам пройти через элементы текущего массива (когда был создан Iterator). Элементы этого массива не изменяются за время существования Iterator. Это возможно потому, что любые действия add, set, remove, clear, .. на CopyOnWriteArrayList создают другой массив, который является копией текущего массива.
CopyOnWriteArrayListEx.java
package org.o7planning.copyonwritearraylist.ex;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteArrayListEx {

    public static void main(String[] args) {
        // Create a CopyOnWriteArrayList object:
        List<String> list = new CopyOnWriteArrayList<String>();
        list.add("A");
        list.add("B");
        list.add("C");
        
        Iterator<String> iterator1 = list.iterator();
        
        list.add("X1");
        list.add("X2");
        
        Iterator<String> iterator2 = list.iterator();
        
        System.out.println("--- Iterator 1: -----");
        while(iterator1.hasNext()) {
            System.out.println(iterator1.next());
        }
        
        System.out.println("--- Iterator 2: -----");
        while(iterator2.hasNext()) {
            System.out.println(iterator2.next());
        }
    }
}
Output:
--- Iterator 1: -----
A
B
C
--- Iterator 2: -----
A
B
C
X1
X2
Действия изменения элементов на самих Iterator(add, set, remove) не поддерживаются. Эти методы бросают UnsupportedOperationException.
Stream
Обход (traversal) элементов CopyOnWriteArrayList через Stream имеет те же результаты, что и Iterator.
CopyOnWriteArrayListEx2.java
package org.o7planning.copyonwritearraylist.ex;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Stream;

public class CopyOnWriteArrayListEx2 {

    public static void main(String[] args) {
        // Create a CopyOnWriteArrayList object:
        List<String> list = new CopyOnWriteArrayList<String>();
        list.add("A");
        list.add("B");
        list.add("C");
        
        Stream<String> stream1 = list.stream();
        
        list.add("X1");
        list.add("X2");
        
        Stream<String> stream2 = list.stream();
        
        System.out.println("--- Stream 1: -----");
        stream1.forEach(System.out::println);
        
        System.out.println("--- Stream 2: -----");
        stream2.forEach(System.out::println);
    }
}
Output:
--- Stream 1: -----
A
B
C
--- Stream 2: -----
A
B
C
X1
X2
Кроме специальных характеристик, упомянутых выше, CopyOnWriteArrayList также является обычным List, вы можете найти другие примеры о List в статье ниже