Conteúdo do Curso
Multithreading in Java
Multithreading in Java
CopyOnWrite 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.
Main
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.
Main
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.
Obrigado pelo seu feedback!