CopyOnWriteArrayList in Java
CopyOnWriteArrayList is a thread-safe, high-performance alternative to ArrayList, designed specifically for read-heavy and write-rare use cases. It belongs to the java.util.concurrent package.
The key idea is simple:
Every write operation creates a new copy of the internal array, ensuring that readers always see a consistent and safe snapshot without locks.
What is CopyOnWriteArrayList?
CopyOnWriteArrayList is a special list where:
- All writes (
add,remove,set) create a new array copy - Reads are extremely fast
- No locking is required for reading
- Iterators are fail-safe (never throw ConcurrentModificationException)
- Perfect for concurrent read-mostly applications
Why “Copy On Write”? (Internal Working)
When you do:
list.add("A");
Internally, it performs:
- Creates a new array
- Copies old elements into the new array
- Adds the new element
- Replaces the old array reference
- Safe in multi-threaded environments
- Ultra-fast reads
- Write operations are expensive (copying large arrays takes time)
Features of CopyOnWriteArrayList
| Feature | Explanation |
|---|---|
| Thread-safe | Built-in concurrency without external synchronization |
| Copy on write mechanism | Every modification creates a new array |
| Fail-safe iterator | No ConcurrentModificationException |
| Read performance | Very fast (no locking) |
| Write performance | Slow (full array copy) |
| Null values | Allowed |
| Use case | Read-heavy, write-rare scenarios |
When Should You Use CopyOnWriteArrayList?
Use it when:
- Reads are very frequent
- Writes are very rare
- You need fast, consistent iteration
- You want to avoid ConcurrentModificationException
- Many threads are reading concurrently
Real-world use cases:
- Caching data
- Application configuration values
- Observer / listener lists
- Messaging subscribers
- Read-only or rarely updated datasets
When NOT to Use It
Avoid CopyOnWriteArrayList when:
- Frequent writes (copying on each write is slow)
- Large lists (copy cost becomes huge)
- Real-time or performance-critical write operations
Basic Example
import java.util.concurrent.CopyOnWriteArrayList;
public class Example {
public static void main(String[] args) {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("A");
list.add("B");
for (String s : list) {
System.out.println(s);
}
}
}
Fail-Safe Iterator Example
CopyOnWriteArrayList iterates over a snapshot, so modifications during iteration don’t cause errors.
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("One");
list.add("Two");
for (String s : list) {
list.add("New"); // Safe — No ConcurrentModificationException
System.out.println(s);
}
Output:
One
Two
("New" will not appear during this iteration because iterator uses a snapshot.)
Important Methods
| Method | Description |
|---|---|
add(E e) | Adds element (creates a new copy) |
remove(Object o) | Removes element (new copy created) |
get(int index) | Very fast read |
set(int index, E element) | Updates element (copy on write) |
iterator() | Returns fail-safe iterator |
Difference Between CopyOnWriteArrayList vs ArrayList vs Vector
| Feature | CopyOnWriteArrayList | ArrayList | Vector |
|---|---|---|---|
| Thread-safe? | Yes (internally uses copy-on-write) | No | Yes (every method synchronized) |
| Performance – Read | Fastest (no locking, snapshot-based) | Fast | Slow (due to locking) |
| Performance – Write | Slow (creates a new array on every write) | Fastest | Slow (global lock) |
| Iterator Type | Fail-safe (no ConcurrentModificationException) | Fail-fast | Fail-fast |
| Used for | Read-mostly, low-write operations | General purpose list | Legacy thread-safe code |
| Synchronization Overhead | Low for reads, high for writes | None | Very high (method-level sync) |
| Allows null? | Yes | Yes | Yes |
| Underlying Structure | Array | Array | Array |
| Package | java.util.concurrent | java.util | java.util |
| Best Use Case | Event listeners, caches, configuration lists | Everyday list usage | Legacy systems needing thread safety |
| Write During Iteration | Safe | Throws ConcurrentModificationException | Throws ConcurrentModificationException |
Points to Remember
- Thread-safe, optimized for concurrent reads
- Writes are expensive because it copies the array
- Iterators are fail-safe
- Ideal for read-mostly applications
- Part of java.util.concurrent
