Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте Колекція CopyOnWrite | Синхронізовані Колекції
Багатопотоковість у Java

bookКолекція CopyOnWrite

Ми вже розглянули багато синхронізованих колекцій, і якщо ви опанували інші, ця буде ще простішою для розуміння.

Приклад із реального життя

Вебзастосунок, який використовує CopyOnWriteArrayList для зберігання підписників на події. Декілька потоків можуть одночасно отримувати список поточних підписників для сповіщення їх про зміни, у той час як інші потоки можуть додавати або видаляти підписників.

Відмінності від інших типів

Колекції CopyOnWrite створюють копію колекції щоразу при внесенні змін, що гарантує, що операції читання не блокуються змінами даних, забезпечуючи таким чином потокобезпечність для читання, хоча операції запису не є потокобезпечними, оскільки виконуються на окремій копії колекції.

CopyOnWrite-подання:

Note
Примітка

Як видно на зображенні, при додаванні нового елемента створюється копія цієї структури даних; усі потоки, які працювали з цією колекцією до її зміни, продовжать свою роботу без жодних проблем, оскільки ці зміни не вплинуть на копію CopyOnWrite, яку вони використовують!

CopyOnWriteArraySet

CopyOnWriteArraySet — це потокобезпечна реалізація множини на основі CopyOnWriteArrayList. Вона гарантує потокобезпечність шляхом створення нової копії базової множини щоразу, коли відбувається зміна, така як додавання або видалення елементів.

Такий підхід особливо корисний, коли множина часто читається і рідко змінюється, оскільки забезпечує послідовне відображення множини для всіх потоків без необхідності синхронізації.

CopyOnWriteArrayList

CopyOnWriteArrayList — це потокобезпечний варіант ArrayList, який забезпечує потокобезпечність шляхом створення нової копії базового масиву при кожній зміні.

Ця конструкція пропонує відмовостійкий ітератор, який не генерує ConcurrentModificationException, оскільки працює зі знімком масиву, зробленим у момент створення ітератора. Найкраще підходить для ситуацій, коли операції читання значно переважають над операціями запису, оскільки накладні витрати на копіювання всього масиву при кожному записі можуть бути значними.

Практичний приклад використання

Методи колекції CopyOnWrite

addIfAbsent(E e): Додає елемент до списку лише у випадку, якщо його ще немає у списку/множині.

Main.java

Main.java

copy
123456789101112131415161718192021
package com.example; import java.util.concurrent.CopyOnWriteArrayList; public class Main { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("apple"); list.add("banana"); // Attempt to add a duplicate element list.addIfAbsent("apple"); // This will not add "apple" again // Adding a new element list.addIfAbsent("orange"); // This will add "orange" System.out.println(list); // Output: [apple, banana, orange] } }

У цьому прикладі "apple" не додається повторно, оскільки вже існує у списку. Метод addIfAbsent() запобігає дублюванню записів, підтримуючи унікальність елементів.

addAllAbsent(Collection<? extends E> c): Додає всі елементи із вказаної колекції до списку/множини, ігноруючи вже існуючі елементи.

Main.java

Main.java

copy
12345678910111213141516171819202122
package com.example; import java.util.Arrays; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class Main { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("apple"); list.add("banana"); List<String> newFruits = Arrays.asList("banana", "cherry", "date"); // Adding elements from the collection, ignoring duplicates list.addAllAbsent(newFruits); System.out.println(list); // Output: [apple, banana, cherry, date] } }

У цьому прикладі "banana" вже присутній у list, тому addAllAbsent() не додасть його знову. Метод гарантує, що лише унікальні елементи з наданої колекції будуть додані до list.

Note
Примітка

Усі інші методи колекцій CopyOnWrite подібні до методів їхніх батьківських колекцій; вони просто копіюють стан колекції щоразу, коли відбуваються зміни.

Обмеження та переваги

😔Обмеження:

Колекції CopyOnWrite мають суттєві обмеження. Вони мають витрати пам'яті через створення нової копії колекції щоразу при зміні, що може бути значним. Такий дизайн робить їх менш придатними для сценаріїв, де потрібні часті зміни даних.

💪Переваги:

З іншого боку, колекції CopyOnWrite мають значні переваги. Вони надзвичайно ефективні для читання даних у багатопотоковому середовищі. Ці колекції працюють особливо добре у ситуаціях, коли операцій читання значно більше, ніж операцій запису, що робить їх чудовим вибором для таких випадків.

Note
Примітка

Однак через копіювання при кожній зміні колекції CopyOnWrite можуть споживати більше пам'яті та не підходять для сценаріїв із частими операціями запису. Вони є найбільш ефективними, коли операції читання переважають над операціями запису.

1. Що відбувається при виклику методу addIfAbsent(E e) у CopyOnWriteArrayList?

2. Чому колекції CopyOnWrite особливо підходять для сценаріїв із частим читанням і рідкісними змінами даних?

question mark

Що відбувається при виклику методу addIfAbsent(E e) у CopyOnWriteArrayList?

Select the correct answer

question mark

Чому колекції CopyOnWrite особливо підходять для сценаріїв із частим читанням і рідкісними змінами даних?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 2. Розділ 7

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

Suggested prompts:

What are some common use cases for CopyOnWrite collections?

Can you explain the main differences between CopyOnWriteArrayList and CopyOnWriteArraySet?

When should I avoid using CopyOnWrite collections?

Awesome!

Completion rate improved to 3.33

bookКолекція CopyOnWrite

Свайпніть щоб показати меню

Ми вже розглянули багато синхронізованих колекцій, і якщо ви опанували інші, ця буде ще простішою для розуміння.

Приклад із реального життя

Вебзастосунок, який використовує CopyOnWriteArrayList для зберігання підписників на події. Декілька потоків можуть одночасно отримувати список поточних підписників для сповіщення їх про зміни, у той час як інші потоки можуть додавати або видаляти підписників.

Відмінності від інших типів

Колекції CopyOnWrite створюють копію колекції щоразу при внесенні змін, що гарантує, що операції читання не блокуються змінами даних, забезпечуючи таким чином потокобезпечність для читання, хоча операції запису не є потокобезпечними, оскільки виконуються на окремій копії колекції.

CopyOnWrite-подання:

Note
Примітка

Як видно на зображенні, при додаванні нового елемента створюється копія цієї структури даних; усі потоки, які працювали з цією колекцією до її зміни, продовжать свою роботу без жодних проблем, оскільки ці зміни не вплинуть на копію CopyOnWrite, яку вони використовують!

CopyOnWriteArraySet

CopyOnWriteArraySet — це потокобезпечна реалізація множини на основі CopyOnWriteArrayList. Вона гарантує потокобезпечність шляхом створення нової копії базової множини щоразу, коли відбувається зміна, така як додавання або видалення елементів.

Такий підхід особливо корисний, коли множина часто читається і рідко змінюється, оскільки забезпечує послідовне відображення множини для всіх потоків без необхідності синхронізації.

CopyOnWriteArrayList

CopyOnWriteArrayList — це потокобезпечний варіант ArrayList, який забезпечує потокобезпечність шляхом створення нової копії базового масиву при кожній зміні.

Ця конструкція пропонує відмовостійкий ітератор, який не генерує ConcurrentModificationException, оскільки працює зі знімком масиву, зробленим у момент створення ітератора. Найкраще підходить для ситуацій, коли операції читання значно переважають над операціями запису, оскільки накладні витрати на копіювання всього масиву при кожному записі можуть бути значними.

Практичний приклад використання

Методи колекції CopyOnWrite

addIfAbsent(E e): Додає елемент до списку лише у випадку, якщо його ще немає у списку/множині.

Main.java

Main.java

copy
123456789101112131415161718192021
package com.example; import java.util.concurrent.CopyOnWriteArrayList; public class Main { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("apple"); list.add("banana"); // Attempt to add a duplicate element list.addIfAbsent("apple"); // This will not add "apple" again // Adding a new element list.addIfAbsent("orange"); // This will add "orange" System.out.println(list); // Output: [apple, banana, orange] } }

У цьому прикладі "apple" не додається повторно, оскільки вже існує у списку. Метод addIfAbsent() запобігає дублюванню записів, підтримуючи унікальність елементів.

addAllAbsent(Collection<? extends E> c): Додає всі елементи із вказаної колекції до списку/множини, ігноруючи вже існуючі елементи.

Main.java

Main.java

copy
12345678910111213141516171819202122
package com.example; import java.util.Arrays; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class Main { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("apple"); list.add("banana"); List<String> newFruits = Arrays.asList("banana", "cherry", "date"); // Adding elements from the collection, ignoring duplicates list.addAllAbsent(newFruits); System.out.println(list); // Output: [apple, banana, cherry, date] } }

У цьому прикладі "banana" вже присутній у list, тому addAllAbsent() не додасть його знову. Метод гарантує, що лише унікальні елементи з наданої колекції будуть додані до list.

Note
Примітка

Усі інші методи колекцій CopyOnWrite подібні до методів їхніх батьківських колекцій; вони просто копіюють стан колекції щоразу, коли відбуваються зміни.

Обмеження та переваги

😔Обмеження:

Колекції CopyOnWrite мають суттєві обмеження. Вони мають витрати пам'яті через створення нової копії колекції щоразу при зміні, що може бути значним. Такий дизайн робить їх менш придатними для сценаріїв, де потрібні часті зміни даних.

💪Переваги:

З іншого боку, колекції CopyOnWrite мають значні переваги. Вони надзвичайно ефективні для читання даних у багатопотоковому середовищі. Ці колекції працюють особливо добре у ситуаціях, коли операцій читання значно більше, ніж операцій запису, що робить їх чудовим вибором для таких випадків.

Note
Примітка

Однак через копіювання при кожній зміні колекції CopyOnWrite можуть споживати більше пам'яті та не підходять для сценаріїв із частими операціями запису. Вони є найбільш ефективними, коли операції читання переважають над операціями запису.

1. Що відбувається при виклику методу addIfAbsent(E e) у CopyOnWriteArrayList?

2. Чому колекції CopyOnWrite особливо підходять для сценаріїв із частим читанням і рідкісними змінами даних?

question mark

Що відбувається при виклику методу addIfAbsent(E e) у CopyOnWriteArrayList?

Select the correct answer

question mark

Чому колекції CopyOnWrite особливо підходять для сценаріїв із частим читанням і рідкісними змінами даних?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 2. Розділ 7
some-alt