CopyOnWriteArraySet
About
CopyOnWriteArraySet
is a thread-safe implementation of the Set
interface. It is backed by a CopyOnWriteArrayList
, meaning it creates a new copy of the underlying array every time a modification (add, remove, etc.) is made. This makes it particularly suitable for use cases where read operations vastly outnumber write operations, as it provides thread-safe iteration without the need for external synchronization.
Features
Thread-Safe: All operations are thread-safe, providing consistent behavior in multi-threaded environments.
No Duplicates: Like all
Set
implementations, it does not allow duplicate elements.Read-Mostly Optimization: Optimized for scenarios with frequent reads and infrequent writes, as reads do not block.
Iterators Are Fail-Safe: Iterators operate on a snapshot of the set at the time they are created, meaning they will not throw
ConcurrentModificationException
.Array-Based Backing: Backed by a dynamically growing array (
CopyOnWriteArrayList
), making iteration very fast but write operations more costly.
Internal Working
Backing Structure
Internally uses a
CopyOnWriteArrayList
to store elements.Each modification creates a new copy of the internal array, ensuring that readers see a consistent and unchanging view of the set.
Add Operation
When a new element is added, a new array is created, the element is added, and the old array is replaced.
Ensures no duplicates by checking if the element already exists.
Remove Operation
Similar to
add
, a new array is created without the specified element, and the old array is replaced.
Thread-Safety
Write operations (
add
,remove
, etc.) are synchronized internally.Read operations (
contains
,iterator
, etc.) do not require synchronization and are very fast.
Snapshot Iterators
Iterators operate on a snapshot of the array taken at the time the iterator was created.
Modifications to the set during iteration will not affect the iterator.
Key Methods
Method
Description
add(E e)
Adds the specified element to the set if it is not already present.
remove(Object o)
Removes the specified element from the set if it exists.
contains(Object o)
Returns true
if the set contains the specified element.
size()
Returns the number of elements in the set.
iterator()
Returns an iterator over the elements in the set.
clear()
Removes all elements from the set.
isEmpty()
Returns true
if the set contains no elements.
toArray()
Returns an array containing all the elements in the set.
Big-O for Operations
Operation
Time Complexity
Add
O(n)
Remove
O(n)
Contains
O(n)
Iteration
O(n)
Limitations
High Write Cost: Write operations (
add
,remove
) are costly because a new array is created on every modification.Memory Usage: Creating a new array for every modification can increase memory usage, especially for large sets.
No Real-Time Updates During Iteration: Iterators work on a snapshot and do not reflect modifications made after the iterator is created.
Not Suitable for High-Write Scenarios: The overhead of copying the entire array makes it impractical for use cases with frequent write operations.
Real-World Usage
Event Listener Management: Used for managing sets of listeners where additions or removals are rare but reads are frequent.
Cache or Configuration: Useful for sets that change rarely but are frequently read in concurrent applications.
Immutable Views: When a consistent snapshot of the data is required without blocking threads during iteration.
Examples
1. Basic Operations
2. Fail-Safe Iteration
3. Concurrent Access
Last updated
Was this helpful?