Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
CopyOnWrite Collection | Synchronized Collections
Multithreading in Java
course content

Course Content

Multithreading in Java

Multithreading in Java

1. Multithreading Basics
2. Synchronized Collections
3. High-level Synchronization Mechanisms
4. Multithreading Best Practices

bookCopyOnWrite Collection

We've explored many synchronized collections together, and if you've mastered the others, you’ll find this one even more straightforward.

Real Life Example

A web application that uses CopyOnWriteArrayList to store event subscribers. Multiple threads can simultaneously retrieve a list of current subscribers to notify them of changes, while other threads can add or remove subscribers.

Differences From Other Types

CopyOnWrite collections create a copy of the collection each time a change is made, ensuring that read operations are not blocked by data changes, thus providing thread safety for reads, although write operations are not thread-safe as they occur on a separate copy of the collection.

CopyOnWrite Views:

Note

As we can see on the picture, when adding a new item, we make a copy of this data structure, all threads that worked with this collection before its change will continue their work without any problems, because these changes will not affect the CopyOnWrite copy they use!

CopyOnWriteArraySet

CopyOnWriteArraySet is a thread-safe implementation of a set based on CopyOnWriteArrayList. It ensures thread-safety by creating a new copy of the base set each time a change, such as adding or removing elements, occurs.

This approach is particularly useful when the set is read frequently and changed infrequently, as it provides a consistent view of the set for all threads without requiring synchronization.

CopyOnWriteArrayList

CopyOnWriteArrayList is a thread-safe variant of ArrayList that ensures thread-safety by creating a new copy of the underlying array each time it is modified.

This design offers a fault-tolerant iterator that does not throw a ConcurrentModificationException because it operates on a snapshot of the array taken at the time the iterator was created. It is best suited for situations where read operations are significantly more frequent than write operations, as the overhead of copying the entire array on each write can be considerable.

Practical Example of Use Case

Methods of the CopyOnWrite collection

addIfAbsent(E e): Adds an element to the list only if it is not already in the list/multiple.

java

Main

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] } }

In this example, "apple" is not added again because it already exists in the list. The addIfAbsent() method prevents duplicate entries, maintaining the uniqueness of elements.

addAllAbsent(Collection<? extends E> c): Adds all elements from the specified collection to the list/multiple, ignoring already existing elements.

java

Main

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] } }

In this example, "banana" is already present in the list, so addAllAbsent() will not add it again. The method ensures that only unique elements from the provided collection are added to the list.

Note

All other methods of CopyOnWrite collections are similar to those of their parent collections; they simply copy the state of the collection whenever changes are made.

Limitations and Advantages

😔Limitations:

CopyOnWrite collections have notable limitations. They incur a memory cost due to creating a new copy of the collection every time a change is made, which can be substantial. This design makes them less suitable for scenarios where frequent data changes are needed.

💪Advantages:

On the flip side, CopyOnWrite collections offer significant advantages. They are highly efficient for reading data in a multi-threaded environment. These collections perform exceptionally well in situations where read operations significantly outnumber write operations, making them an excellent choice for such use cases.

Note

However, due to copying at every change, CopyOnWrite collections can consume more memory and are not suitable for scenarios with frequent write operations. They are most effective when read operations predominate over write operations.

1. What happens when you call the `addIfAbsent(E e)` method in CopyOnWriteArrayList?
2. Why are `CopyOnWrite` collections particularly suitable for scenarios with frequent reads and infrequent data changes?
What happens when you call the `addIfAbsent(E e)` method in CopyOnWriteArrayList?

What happens when you call the addIfAbsent(E e) method in CopyOnWriteArrayList?

Select the correct answer

Why are `CopyOnWrite` collections particularly suitable for scenarios with frequent reads and infrequent data changes?

Why are CopyOnWrite collections particularly suitable for scenarios with frequent reads and infrequent data changes?

Select the correct answer

Everything was clear?

How can we improve it?

Thanks for your feedback!

Section 2. Chapter 7
some-alt