CopyOnWriteArraySet
это младший брат класса
CopyOnWriteArrayList
. Это специализированный набор классов, добавленных в JDK 1.5 вместе с их более популярным двоюродным братом
ConcurrentHashMap
. Они являются частью
concurrent collection framework
и расположены в пакете
java.util.concurrent
.
CopyOnWriteArraySet
лучше всего подходит для read-only коллекций, размер которых достаточно мал, чтобы их скопировать, если произойдут некоторые изменяющие операции. Например, вы можете использовать
CopyOnWriteArraySet
для хранения объекта при запуске приложения, и дать множеству других потоков доступ к этому объекту на протяжении жизненного цикла приложения. Если новое состояние или объект приходят в течение этого времени, он также может быть добавлен в этот
Set
, со стоимостью создания нового массива.
Одна из самых важных вещей, которую стоит знать о
CopyOnWriteArraySet
это то, что он реализован при помощи
CopyOnWriteArrayList
. Это означает, что
CopyOnWriteArraySet
также разделяет все основные свойства
CopyOnWriteArrayList
. Еще одна важная вещь, которую стоит запомнить: итераторы этого класса коллекции не поддерживают операцию
remove()
. Попытка удалить элемент во время интегрирования приведет к выбросу
UnsupportedOperationException
. Это сделано чтобы гарантировать скорость во время обхода. Обход этой реализации
Set
, используя итератор, осуществляется достаточно быстро, и во время него исключены вмешательства других потоков. В своей работе итераторы опираются на моментальный снимок массива, который был сделан во время создания итератора.
Короче говоря, используйте
CopyOnWriteArraySet
если
set
достаточно мал, чтобы копировать его при добавлении, задании значения или удалении объектов, и основной целью является чтение обновляемых от случая к случаю данных. Кроме того, если вы хотите удалить элементы во время итерации, не используйте эту реализацию, потому что ее итератор не поддерживает
remove()
, и бросает
java.lang.UnsupportedOperationException
, как показано ниже:
[RAJ] Event received : FOUR
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.concurrent.CopyOnWriteArrayList$COWIterator.remove(Unknown Source)
at Publisher.notifySubs(HelloHP.java:43)
at HelloHP.main(HelloHP.java:23)
CopyOnWriteArraySet пример на Java
Вот готовая программа на Java показывающая, как использовать
CopyOnWriteArraySet
. В нашем примере мы использовали шаблон проектирования "Издатель-подписчик" (англ.
publisher-subscriber pattern), чтобы продемонстрировать его использование. Большинство подписчиков подписаны во время пуска приложения и главной задачей издателя является их перебор и уведомление о каких-либо обновлениях. Время от времени может случаться добавление и удаление подписчика . Так как нам нужен быстрый обход,
CopyOnWriteArraySet
является хорошим выбором, особенно в многопоточной среде, где один поток может добавить абонента, а другой поток обрабатывает обновления.
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* Java program to demonstrate how to use CopyOnWriteArraySet in Java. Remember,
* CopyOnWriteArraySet doesn't support remove() operation.
*
* @author Javin Paul
*/
public class CopyOnWriteArraySetDemo{
public static void main(String args[]) {
Publisher cricNext = new Publisher();
SubScriber raj = new SubScriber("RAJ");
SubScriber adom = new SubScriber("ADOM");
cricNext.addSubscriber(raj);
cricNext.addSubscriber(adom);
cricNext.notifySubs("FOUR");
cricNext.notifySubs("SIX");
}
}
class Publisher {
private CopyOnWriteArraySet setOfSubs = new CopyOnWriteArraySet();
public void addSubscriber(SubScriber sub) {
setOfSubs.add(sub);
}
public void notifySubs(String score) {
Iterator itr = setOfSubs.iterator();
while (itr.hasNext()) {
SubScriber sub = itr.next();
sub.receive(score);
//itr.remove(); // not allowed, throws UnsupportedOperationException
}
}
}
class SubScriber {
private String _name;
public SubScriber(String name) {
this._name = name;
}
public void receive(String score) {
System.out.printf("[%s] Event received : %s %n", _name, score);
}
}
Output:
[RAJ] Event received : FOUR
[ADOM] Event received : FOUR
[RAJ] Event received : SIX
[ADOM]Event received : SIX
Что нужно запомнить
CopyOnWriteArraySet
реализует интерфейсы
Collection
и
Set
, а также, добавленный в JDK 1.5, вместе с другой специальной реализацией
Set
'а,
EnumSet
. Это также
Set
, который использует внутренний
CopyOnWriteArrayList
для всех своих операций. Таким образом, он разделяет те же основные свойства этого класса. Так как это не
SortedSet
, порядок элементов не гарантируется в течение итерации.
CopyOnWriteArraySet
лучше всего подходит для приложений, в которых:
- Размеры
Set
'ов, как правило остаются небольшими.
- Операции
read-only
значительно превосходят операции, изменяющие объекты.
- Вы должны предотвратить помехи между потоками во время обхода
Set
'а.
- Еще одним преимуществом
CopyOnWriteArraySet
является потокобезопасность. Эта коллекция поддерживает параллелизм.
- Мутативные операции (добавление, изменение, удаление и т.д.) являются дорогостоящими, так как они, как правило, требуют копирования всего базового массива.
- Итераторы не поддерживают мутативную операцию удаления.
- Обход используя итератор достаточно быстр и во время него исключены вмешательства других потоков. В своей работе итераторы опираются на моментальный снимок массива, который был сделан во время создания итератора.
На этом все об использовании
CopyOnWriteArraySet
в Java. Как я сказал, он является младшим братом
CopyOnWriteArrayList
. Так что если вы понимаете хотя бы один из них, то сможете использовать и другой. Единственное отличие в том, что один является
List
'ом а другой
Set
'ом, таким образом это влечет за собой унаследование всех отличий между этими структурами данных в Java. Например, в
List
важен порядок расположения элементов, и он может содержать дубликаты. В то время как
Set
является неупорядоченным, но не позволяет дублирование объектов.
Всегда помните, что
CopyOnWriteArraySet
это специализированный
Collection
класс. Его стоит использовать только когда условия являются благоприятными. В любом другом случае можно пользоваться реализациями общего назначения. Например,
HashSet
,
LinkedHashSet
или синхронизированными классами коллекций.
Оригинал:
How to use CopyOnWriteArraySet in Java with Example
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ