CopyOnWriteArraySet
To młodszy brat tej klasy
CopyOnWriteArrayList
. Jest to wyspecjalizowany zestaw klas dodanych w JDK 1.5 wraz z ich bardziej popularnym kuzynem
ConcurrentHashMap
. Są częścią
concurrent collection framework
opakowania i znajdują się w nim
java.util.concurrent
.
CopyOnWriteArraySet
Najlepiej nadaje się do kolekcji tylko do odczytu, które są wystarczająco małe, aby można je było skopiować w przypadku wystąpienia pewnych operacji modyfikujących. Można na przykład użyć
CopyOnWriteArraySet
do przechowywania obiektu podczas uruchamiania aplikacji i mieć dostęp do tego obiektu przez wiele innych wątków przez cały cykl życia aplikacji. Jeśli w tym czasie pojawi się nowy stan lub obiekt, można go również dodać do tego
Set
, kosztem utworzenia nowej tablicy. Jedną z najważniejszych rzeczy, o których należy wiedzieć,
CopyOnWriteArraySet
jest to, że jest ona implementowana przy użyciu platformy
CopyOnWriteArrayList
. Oznacza to, że
CopyOnWriteArraySet
ma również wszystkie podstawowe właściwości
CopyOnWriteArrayList
. Kolejną ważną rzeczą do zapamiętania jest to, że iteratory tej klasy kolekcji nie obsługują metody
remove()
. Próba usunięcia elementu podczas integracji zakończy się wynikiem odstającym
UnsupportedOperationException
. Ma to na celu zapewnienie prędkości podczas pełzania. Przechodzenie przez tę implementację
Set
za pomocą iteratora jest dość szybkie i pozwala uniknąć zakłóceń ze strony innych wątków. Aby działać, iteratory opierają się na migawce tablicy wykonanej podczas tworzenia iteratora. Krótko mówiąc, użyj
CopyOnWriteArraySet
, jeśli jest
set
wystarczająco mały, aby skopiować go podczas dodawania, ustawiania lub usuwania obiektów, a głównym celem jest odczyt sporadycznie aktualizowanych danych. Ponadto, jeśli chcesz usunąć elementy podczas iteracji, nie używaj tej implementacji, ponieważ jej iterator nie obsługuje
remove()
i nie rzuca
java.lang.UnsupportedOperationException
, jak pokazano poniżej:
[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)
Przykład CopyOnWriteArraySet w Javie
Oto gotowy program Java pokazujący, jak używać
CopyOnWriteArraySet
. W naszym przykładzie użyliśmy wzorca wydawca
-subskrybent , aby zademonstrować jego użycie. Większość subskrybentów subskrybuje się w momencie uruchomienia aplikacji, a głównym zadaniem wydawcy jest ich zliczenie i powiadomienie o wszelkich aktualizacjach. Od czasu do czasu może nastąpić dodanie i usunięcie abonenta. Ponieważ potrzebujemy szybkiego obejścia,
CopyOnWriteArraySet
jest to dobry wybór, zwłaszcza w środowisku wielowątkowym, w którym jeden wątek może dodawać subskrybenta, podczas gdy inny wątek obsługuje aktualizacje.
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);
}
}
Wyjście:
[RAJ] Event received : FOUR
[ADOM] Event received : FOUR
[RAJ] Event received : SIX
[ADOM]Event received : SIX
O czym pamiętać
CopyOnWriteArraySet
implementuje interfejsy
Collection
i
Set
, a także dodane w JDK 1.5 wraz z inną niestandardową implementacją
Set
„a,
EnumSet
. Jest to również
Set
taki, który wykorzystuje dane wewnętrzne
CopyOnWriteArrayList
do wszystkich swoich operacji. Zatem ma te same podstawowe właściwości co ta klasa. Ponieważ tak nie jest
SortedSet
, kolejność elementów nie jest gwarantowana podczas iteracji.
-
CopyOnWriteArraySet
Najlepiej nadaje się do zastosowań, w których:
- Rozmiary
Set
„s” zwykle pozostają małe.
- Operacje
read-only
znacznie przewyższają operacje modyfikujące obiekty.
- Należy zapobiegać przenikaniu wątków podczas przechodzenia
Set
.
- Kolejną zaletą
CopyOnWriteArraySet
jest bezpieczeństwo gwintu. Ta kolekcja obsługuje współbieżność.
- Operacje mutacyjne (dodawanie, modyfikowanie, usuwanie itp.) są kosztowne, ponieważ zazwyczaj wymagają skopiowania całej podstawowej tablicy.
- Iteratory nie obsługują operacji usuwania mutacyjnego.
- Przechodzenie za pomocą iteratora jest dość szybkie i podczas niego wykluczona jest ingerencja innych wątków. Aby działać, iteratory opierają się na migawce tablicy wykonanej podczas tworzenia iteratora.
To wszystko na temat użycia
CopyOnWriteArraySet
w Javie. Jak powiedziałem, jest młodszym bratem
CopyOnWriteArrayList
. Jeśli więc rozumiesz przynajmniej jeden z nich, możesz użyć drugiego. Jedyna różnica polega na tym, że jedna to
List
„”, a druga
Set
to „”, więc pociąga to za sobą dziedziczenie wszystkich różnic między tymi strukturami danych w Javie. Na przykład
List
kolejność elementów jest ważna i może zawierać duplikaty. Choć
Set
nieuporządkowany, nie pozwala na powielanie obiektów. Zawsze pamiętaj, że
CopyOnWriteArraySet
jest to klasa specjalistyczna
Collection
. Należy go stosować tylko wtedy, gdy warunki są sprzyjające. W każdym innym przypadku możesz użyć implementacji ogólnego przeznaczenia. Na przykład
HashSet
lub
LinkedHashSet
zsynchronizowane klasy kolekcji. Oryginał:
Jak używać CopyOnWriteArraySet w Javie z przykładem
GO TO FULL VERSION