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

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

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

CopyOnWriteArraySet — это потокобезопасная реализация интерфейса Set в Java, основанная на механизме "копирование при записи" (Copy-On-Write). Эта структура данных является частью пакета java.util.concurrent, предназначенного для работы в многопоточных средах. Она предоставляет возможность безопасного использования множества элементов в условиях многопоточности без необходимости явной синхронизации.

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

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

Copy-On-Write Механизм:
Механизм "копирование при записи" подразумевает, что при изменении содержимого множества создается новая копия массива, содержащего элементы. Это обеспечивает отсутствие блокировок при чтении, что повышает производительность при большом количестве потоков, выполняющих операции чтения.

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

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

Семантика семейств методов:
Все методы, которые изменяют коллекцию, такие как add, remove, и clear, создают новую копию массива. Методы чтения, такие как contains, iterator, и size, работают с неизменяемым массивом, что обеспечивает высокую скорость.


Внутреннее устройство CopyOnWriteArraySet

Основы внутренней реализации:
CopyOnWriteArraySet построен на основе CopyOnWriteArrayList, и его внутреннее устройство напрямую связано с этой коллекцией. Внутри CopyOnWriteArraySet содержится экземпляр CopyOnWriteArrayList, который используется для хранения элементов.
public class CopyOnWriteArraySet<E> implements Set<E>, Cloneable, Serializable {
private final CopyOnWriteArrayList<E> al;

public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();
}

// другие методы...
}


Гарантия уникальности элементов:

Поскольку CopyOnWriteArraySet реализует интерфейс Set, он гарантирует уникальность элементов. Для этого используется метод contains из CopyOnWriteArrayList, который проверяет, содержится ли элемент в массиве перед его добавлением.
public boolean add(E e) {
return al.addIfAbsent(e);
}


Преимущества и недостатки:

Основное преимущество CopyOnWriteArraySet заключается в полной потокобезопасности и отсутствии необходимости синхронизации при чтении. Однако цена этого преимущества — высокая стоимость операций изменения, таких как добавление или удаление элементов, из-за необходимости создания новой копии массива.
Преимущества использования CopyOnWriteArraySet

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

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

Гарантия уникальности элементов:
CopyOnWriteArraySet автоматически поддерживает уникальность элементов, что упрощает работу с множествами данных.

Ссылки на полезные статьи (спасибо авторам за проделанную работу) :
https://javarush.com/groups/posts/1439-kak-poljhzovatjhsja-copyonwritearrayset-v-java-s-primerom-perevod
https://www.geeksforgeeks.org/copyonwritearrayset-in-java/

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

add(E e):

Добавляет элемент в множество, если он отсутствует. Возвращает true, если элемент был добавлен, и false, если элемент уже присутствует в множестве.
CopyOnWriteArraySet<String> set = new CopyOnWriteArraySet<>();
set.add("Java");
set.add("Concurrency");
boolean added = set.add("Java"); // Вернет false, так как "Java" уже есть в множестве


remove(Object o):

Удаляет указанный элемент из множества. Возвращает true, если элемент был удален, и false, если элемента не было в множестве.

boolean removed = set.remove("Java");  // Вернет true, если "Java" была удалена


contains(Object o):

Проверяет, содержится ли указанный элемент в множестве. Возвращает true, если элемент присутствует, и false, если отсутствует.
boolean contains = set.contains("Concurrency");  // Вернет true, если "Concurrency" есть в множестве


size():

Возвращает количество элементов в множестве.
int size = set.size();  // Возвращает количество элементов в множестве


isEmpty():

Проверяет, пусто ли множество. Возвращает true, если множество пусто, и false, если нет.
boolean isEmpty = set.isEmpty();  // Вернет true, если множество пусто


clear():

Удаляет все элементы из множества, оставляя его пустым.
set.clear();  // Очищает множество


iterator():

Возвращает итератор для обхода элементов в множестве. Итератор безопасен для многопоточного использования, однако не гарантирует отражение изменений, сделанных другими потоками после создания итератора.
for (String element : set) {
System.out.println(element);
}


toArray():

Преобразует множество в массив. Возвращает массив, содержащий все элементы множества.
Object[] array = set.toArray();


equals(Object o):

Проверяет, равен ли текущий набор указанному объекту. Два множества считаются равными, если они содержат одинаковые элементы.
CopyOnWriteArraySet<String> anotherSet = new CopyOnWriteArraySet<>();
boolean isEqual = set.equals(anotherSet); // Сравнивает два множества


Примеры использования
CopyOnWriteArraySet

Хранение активных сессий пользователя:

В веб-приложениях можно использовать CopyOnWriteArraySet для хранения активных сессий пользователя, так как чтение информации о сессиях происходит чаще, чем их добавление или удаление.
CopyOnWriteArraySet<Session> activeSessions = new CopyOnWriteArraySet<>();

// Добавление новой сессии
activeSessions.add(newSession);

// Проверка наличия активной сессии
if (activeSessions.contains(currentSession)) {
// Обработка активной сессии
}

// Удаление завершенной сессии
activeSessions.remove(expiredSession);


Подписчики на события:
В системах, использующих паттерн "наблюдатель" (Observer), CopyOnWriteArraySet может использоваться для хранения подписчиков на события.
CopyOnWriteArraySet<EventListener> listeners = new CopyOnWriteArraySet<>();

// Добавление нового подписчика
listeners.add(newEventListener);

// Оповещение всех подписчиков о событии
for (EventListener listener : listeners) {
listener.onEvent(event);
}
Этот подход позволяет избежать проблем с одновременным изменением списка подписчиков и оповещением, обеспечивая безопасность и корректность работы в многопоточной среде.


Многопоточная работа с уникальными значениями:

CopyOnWriteArraySet идеально подходит для работы с множествами данных в многопоточной среде, где важна уникальность значений. Например, при разработке кеша для хранения уникальных запросов.
CopyOnWriteArraySet<String> queryCache = new CopyOnWriteArraySet<>();

// Добавление запроса в кеш
queryCache.add("SELECT * FROM users WHERE id=1");

// Проверка наличия запроса в кеше
if (queryCache.contains("SELECT * FROM users WHERE id=1")) {
// Обработка запроса из кеша
}


#Java #Training #Medium #CopyOnWriteArraySet