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;
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);
}
}
}
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 в Java with Example
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ