ArrayList are not Synchronized , so we have to consider this issue when we deal with threads. Some things we can do are use Collections.synchronizedList() for thread safety.
This means that only one thread can modify the list at a time, preventing race conditions and ensuring data consistency in a multi threaded environment.
Collections.synchronizedList()
is a static factory method in Java that returns a thread-safe (synchronized) wrapper for a specified List. It is part of the java.util.Collections class and ensures that all access to the underlying list is properly synchronized, which is crucial in a multi-threaded environment where multiple threads might access and modify the list simultaneously.
How it works
The method works by wrapping the given non-thread-safe list (such as an ArrayList or LinkedList) inside a new object. All public methods of this wrapper object (like add(), remove(), get(), etc.) are synchronized on an internal lock, ensuring that only one thread can access the list's methods at any given time.
Although individual methods are synchronized, compound operations like iteration are not automatically protected. If one thread is iterating over the list and another thread modifies it, a ConcurrentModificationException can occur. To prevent this, you must manually synchronize the list when iterating over it.
Example of proper iteration:
java
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// ... add elements in a thread-safe way ...synchronized (syncList) {
for (Stringitem : syncList) {
System.out.println(item);
}
}
Performance overhead
Using synchronizedList() comes with a performance cost. Since every method call acquires a lock on the entire list, it can become a bottleneck in scenarios with high contention (many threads frequently accessing the list). For applications that need better scalability, more specialized collections from the java.util.concurrent package may be a better choice.
import java.util.concurrent.CopyOnWriteArrayList;
CopyOnWriteArrayList<String> list = newCopyOnWriteArrayList<>();
synchronizedList vs. CopyOnWriteArrayList
CopyOnWriteArrayList is a concurrent collection often compared to Collections.synchronizedList(). The main differences lie in how they handle reads and writes.
Characteristic
Collections.synchronizedList()
CopyOnWriteArrayList
Thread Safety
Achieves thread safety by locking the entire list for every read and write operation.
Achieves thread safety for writes by creating a new copy of the underlying array, so reads can proceed without a lock.
Iterator Behavior
Its iterator is "fail-fast" and will throw a ConcurrentModificationException if the list is modified during iteration without external synchronization.
Its iterator is "fail-safe" and operates on a snapshot of the list. It will not throw a ConcurrentModificationException and will not reflect changes made after the iterator was created.
Performance
Better performance when there are more write operations than reads, as writing does not involve creating a new copy.
Better performance in scenarios with many more read operations than writes, as read operations are non-blocking.
Memory Usage
Uses less memory, as new copies are not made on every write.
Uses more memory, as every write operation creates and copies a new internal array.
When to use Collections.synchronizedList()
For simple use cases where the number of threads accessing the list is low and synchronization is straightforward.
When you need to make an existing, non-thread-safe list implementation thread-safe with minimal code changes.
When the number of write operations is significantly higher than the number of read operations.
When you require a "fail-fast" iterator to detect concurrent modifications during iteration.
To address that issue and to iterate over the synchronized list.
Crucially, iteration over synchronized collections requires external synchronization.
This is because the synchronization provided by synchronizedList() only covers individual operations,
not compound operations like iterating through the entire list.
No comments:
Post a Comment