Java for Beginner
677 subscribers
546 photos
155 videos
12 files
836 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
CopyOnWriteArrayList, особенности и преимущества

CopyOnWriteArrayList — это потокобезопасная реализация интерфейса List в Java, которая отличается тем, что при каждой операции изменения создает копию массива. Это делает CopyOnWriteArrayList особенно подходящей для сценариев, где чтение данных происходит гораздо чаще, чем запись.

Особенности CopyOnWriteArrayList

Потокобезопасность:
Все методы, изменяющие содержимое списка, синхронизированы, что обеспечивает безопасность при использовании в многопоточной среде без явной необходимости в дополнительных блокировках.

Immutable при чтении:
Операции чтения (такие как get(), iterator(), и т.д.) не требуют блокировок и происходят в постоянное время (O(1)), так как они работают с неизменяемыми копиями массива.

Создание копий при изменении:
Каждая операция записи (добавление, удаление, обновление элемента) создает новую копию всего внутреннего массива. Это может быть дорогостоящим по памяти и времени при частых операциях записи.

Консистентные итераторы:
Итераторы, возвращаемые
CopyOnWriteArrayList, никогда не выбрасывают ConcurrentModificationException, потому что они работают с моментальной копией данных на момент их создания.

Отсутствие возможности удаления через итератор:
Методы итератора, такие как remove(), не поддерживаются и выбрасывают UnsupportedOperationException.


Преимущества CopyOnWriteArrayList

Высокая производительность для чтения:
В сценариях, где множество потоков активно читают данные и изменения происходят редко, CopyOnWriteArrayList обеспечивает высокую производительность благодаря отсутствию необходимости синхронизации для операций чтения.

Предсказуемое поведение:
Из-за неизменности копий массива при чтении, итераторы не видят промежуточных состояний, что делает поведение программы более предсказуемым.

Безопасность в многопоточных средах:
CopyOnWriteArrayList идеален для программ, которые требуют безопасного доступа к коллекции из нескольких потоков без использования внешних блокировок.

Основные особенности внутреннего устройства

Массив как основа хранения:
Внутренне
CopyOnWriteArrayList использует массив для хранения элементов. Этот массив называется array и является volatile-полем, что гарантирует видимость изменений между потоками.

Копирование при записи:
При выполнении любой операции, изменяющей содержимое списка (например, add(), remove(), set()), создается новая копия массива с внесенными изменениями. Это обеспечивает неизменяемость исходного массива, используемого для чтения, и потокобезопасность операций.

Синхронизация методов:
Методы, которые изменяют содержимое списка, синхронизированы, чтобы гарантировать, что только один поток может выполнять изменение в любой момент времени.

Чтение без блокировок:
Операции чтения (такие как get(), size(), итерация) не требуют блокировок, так как они работают с неизменяемыми копиями массива.

Преимущества:

Потокобезопасность:
CopyOnWriteArrayList позволяет безопасно использовать коллекцию в многопоточной среде без явной синхронизации.
Высокая производительность для чтения: Благодаря неизменяемости массивов, операции чтения очень быстрые.
Консистентные итераторы: Итераторы никогда не выбрасывают ConcurrentModificationException, так как они работают с моментальной копией данных.

Недостатки:

Высокие затраты на изменение: Из-за копирования массива при каждой операции изменения, CopyOnWriteArrayList может быть неэффективным для частых операций записи.
Высокие затраты памяти: Копирование массива создает дополнительную нагрузку на память.

Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://for-each.dev/lessons/b/-java-copy-on-write-arraylist
https://www.baeldung.com/java-copy-on-write-arraylist

#Java #Training #Medium #CopyOnWriteArrayList
Основные методы CopyOnWriteArrayList и примеры использования

Добавление элементов:

add(E e): добавляет элемент в конец списка.
add(int index, E element): вставляет элемент по указанному индексу.
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("Apple");
list.add(1, "Banana");


Удаление элементов:

remove(Object o): удаляет первое вхождение указанного элемента.
remove(int index): удаляет элемент по указанному индексу.
list.remove("Banana");
list.remove(0);


Обновление элементов:

set(int index, E element): заменяет элемент по указанному индексу новым элементом.
list.set(0, "Orange");


Получение элементов:

get(int index): возвращает элемент по указанному индексу.
String fruit = list.get(0);


Проверка содержимого:

contains(Object o): проверяет, содержится ли указанный элемент в списке.
size(): возвращает количество элементов в списке.

boolean containsApple = list.contains("Apple");
int size = list.size();


Итерация по элементам:

iterator(): возвращает итератор по элементам списка.
for (String fruit : list) {
System.out.println(fruit);
}


Примеры использования
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.List;
import java.util.Iterator;

public class CopyOnWriteArrayListMethodsExample {
public static void main(String[] args) {
List<String> list = new CopyOnWriteArrayList<>();

// Добавление элементов
list.add("Apple");
list.add("Banana");
list.add("Cherry");
System.out.println("After adding elements: " + list);

// Вставка элемента
list.add(1, "Orange");
System.out.println("After insertion: " + list);

// Обновление элемента
list.set(2, "Mango");
System.out.println("After updating: " + list);

// Удаление элемента по индексу
list.remove(3);
System.out.println("After removing by index: " + list);

// Удаление элемента по значению
list.remove("Apple");
System.out.println("After removing by value: " + list);

// Проверка содержимого
boolean containsBanana = list.contains("Banana");
System.out.println("Contains Banana: " + containsBanana);

// Получение элемента
String fruit = list.get(0);
System.out.println("Element at index 0: " + fruit);

// Итерация по элементам
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println("Iterating: " + iterator.next());
}

// Размер списка
int size = list.size();
System.out.println("Size of list: " + size);

// Очистка списка
list.clear();
System.out.println("After clearing: " + list);
}
}


#Java #Training #Medium #CopyOnWriteArrayList