Статьи

Как использовать CopyOnWriteArraySet в Java с примером

CopyOnWriteArraySet — это младший брат класса CopyOnWriteArrayList. Это специальные коллекции классов, которые были добавлены в JDK 1.5 вместе с их самым популярным двоюродным братом ConcurrentHashMap . Они являются частью среды параллельного сбора и находятся в пакете java.util.concurrent.
CopyOnWriteArraySet лучше всего подходит в качестве коллекции, доступной только для чтения, размер которой достаточно мал, чтобы ее можно было скопировать, если происходит какая-либо мутативная операция, например, вы можете использовать CopyOnWriteArraySet для хранения объекта при запуске приложения и позволить нескольким потокам приложения получить к ним доступ в течение времени жизни приложения. Если в течение этого времени появляется новое условие или объект, его также можно добавить в этот набор, что повлечет за собой затраты на создание нового массива. Одна из самых важных вещей, которые нужно знать о CopyOnWriteArraySet, это то, что он поддерживается CopyOnWriteArrayList , что означает, что он также разделяет все основные свойства CopyOnWriteArrayList. Также важно помнить, что итераторы этого класса коллекции не поддерживают операцию удаления (), попытка удалить элемент во время итерации приведет к исключению UnSupportedOperationException. Это сделано для обеспечения скорости во время обхода, поэтому реализация этого набора с использованием Iterator выполняется быстро и не может сталкиваться с помехами от других потоков. Итераторы фактически полагаются на неизменные снимки массива во время создания итераторов. Короче говоря, используйте CopyOnWriteArraySet, если набор достаточно мал для копирования при добавлении, установке или удалении, и основная цель — чтение данных с периодическими обновлениями. Также, если вы хотите удалить элементы во время итерации, не используйте эту реализацию Set, потому что ее итератор не поддерживает remove () и выдает исключение java.lang.UnsupportedOperationException, как показано ниже:

1
2
3
4
5
[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 . В нашем примере мы использовали шаблон подписчика издателя, чтобы продемонстрировать его использование. Большинство подписчиков подписались во время запуска, и главная задача издателя — перебирать их и уведомлять их обо всех обновлениях. Иногда возможно добавление и удаление подписчика. Поскольку нам нужен быстрый обход, CopyOnWriteArraySet является хорошим выбором, особенно в многопоточной среде, где один поток может добавить подписчика, в то время как другой поток обрабатывает обновления.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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 . Это также набор, который использует внутренний CopyOnWriteArrayList для всех своих операций. Таким образом, он имеет те же основные свойства этого класса. Это не SortedSet, поэтому порядок элементов не гарантируется во время итерации.

CopyOnWriteArraySet в Java с примером

  1. CopyOnWriteArraySet лучше всего подходит для приложений, в которых размеры набора обычно остаются небольшими, операции только для чтения значительно превосходят число операций с изменением, и вам необходимо предотвращать помехи между потоками во время обхода.
  2. Еще одно преимущество CopyOnWriteArraySet — безопасность потоков, это параллельная коллекция .
  3. Мутативные операции (добавление, установка, удаление и т. Д.) Являются дорогостоящими, поскольку они обычно требуют копирования всего базового массива.
  4. Итераторы не поддерживают мутативную операцию удаления.
  5. Обход через итераторы быстрый и не может столкнуться с помехами из других потоков. Итераторы полагаются на неизменные снимки массива во время создания итераторов.

Это все о том, как использовать CopyOnWriteArraySet в Java . Как я уже сказал, это маленький брат CopyOnWriteArrayList, поэтому, если вы понимаете один из них, вы можете использовать другие. Единственное отличие состоит в том, что эти два являются одним списком, а другое — множеством, но в этом вся разница между множеством и списком в Java . Например, List упорядочен, позволяет дублировать, а Set неупорядочен, но не позволяет дублировать. Всегда помните, что CopyOnWriteArraySet является классом Collection специального назначения, и его следует использовать только при благоприятных условиях, в противном случае придерживайтесь реализации Set общего назначения, например HashSet, LinkedHashSet или классов синхронизированной коллекции.