In what situations is the CopyOnWriteArrayList suitable?
As stated on this link:
CopyOnWriteArrayList is a concurrent Collection class introduced in Java 5 Concurrency API along with its popular cousin ConcurrentHashMap
in Java.
CopyOnWriteArrayList
implements List interface like ArrayList
, Vector
and LinkedList
but its a thread-safe collection and it achieves its thread-safety in a slightly different way than Vector or other thread-safe collection class.
As name suggest CopyOnWriteArrayList creates copy of underlying
ArrayList with every mutation operation e.g. add or set. Normally
CopyOnWriteArrayList is very expensive because it involves costly
Array copy with every write operation but its very efficient if you
have a List where Iteration outnumber mutation e.g. you mostly need to
iterate the ArrayList and don't modify it too often.Iterator of CopyOnWriteArrayList is fail-safe and doesn't throw
ConcurrentModificationException even if underlying
CopyOnWriteArrayList is modified once Iteration begins because
Iterator is operating on separate copy of ArrayList. Consequently all
the updates made on CopyOnWriteArrayList is not available to Iterator.
To get the most updated version do a new read like list.iterator();
That being said, updating this collection alot will kill performance. If you tried to sort a CopyOnWriteArrayList
you'll see the list throws an UnsupportedOperationException
(the sort invokes set on the collection N times). You should only use this read when you are doing upwards of 90+% reads.
When it's applicable to use CopyOnWriteArrayList
Based on the javadoc,
A thread-safe variant of java.util.ArrayList in which all mutative
operations (add, set, and so on) are implemented by making a fresh
copy of the underlying array.
As you can see, any modification to the container is costly especially when the size of data in the container is big.
It's better to use CopyOnWriteArrayList
when the frequency of modification is low. As suggested by JCIP,
the copy-on-write collections are reasonable to use only when
iteration is far more common than modification.
For example the event-notification system. It will iterate the container every time an event needs to be notified but will only be modified when the observer is changed. The occurrence of the former is with high frequency and the latter is with low frequency.
CopyOnWriteArrayList suitable only for iterations and not random access reads
When you use iterator to traversal the CopyOnWriteArrayList, you will get a snapshot of list when you calling the iterator(), and future modification will not affect your snapshot so you will always loop through the data copy from the time you call iterator.
For random access loop, it will get the data from current fresh copy of list. And if some modification occurs, the future random access will read the modified list and may cause some synchronize problems. So a ReadWriteLock will be helpful here to make the traversal thread-safe.
How can CopyOnWriteArrayList be thread-safe?
If you look at the underlying array reference you'll see it's marked as volatile
. When a write operation occurs (such as in the above extract) this volatile
reference is only updated in the final statement via setArray
. Up until this point any read operations will return elements from the old copy of the array.
The important point is that the array update is an atomic operation and hence reads will always see the array in a consistent state.
The advantage of only taking out a lock for write operations is improved throughput for reads: This is because write operations for a CopyOnWriteArrayList
can potentially be very slow as they involve copying the entire list.
When is CopyOnWriteArraySet useful to achieve thread-safe HashSet?
It is useful when you have a small set of element for a thread safe collection.
One example is a Set of listeners. You need to ensure uniqueness and iterate over them efficiently.
BTW CopyOnWriteArraySet has the lowest overhead on a per reference basis. It can be as little as 1/6 the size of the other collections. This is particularly useful if you have a lot of them.
while Set data structure is for high performance contains operation, could anybody explain this?
COWAS is more efficient in terms of memory and it's contains
is faster for small collections than the alternatives. What is "high performance" depends on the use case.
CopyOnWriteArrayList is too slow
CopyOnWriteArrayList
is the preferred option ONLY WHEN there are very less number of writes and huge number of reads (if multiple threads are accessing this list)
Is there a concurrent List in Java's JDK?
There is a concurrent list implementation in java.util.concurrent. CopyOnWriteArrayList in particular.
Related Topics
Convert Arraylist into 2D Array Containing Varying Lengths of Arrays
String.Format() to Format Double in Java
Checking for a Null Int Value from a Java Resultset
Session.Connection() Deprecated on Hibernate
How to Return JSON Data from Spring Controller Using @Responsebody
This: Cannot Use This in Static Context
Giving 'Java.Library.Path' in Netbeans for .Dll/.So Files
How to Parse Dynamic JSON Fields with Gson
Could Not Find Method Compile() for Arguments Gradle
How to Disable Javac's Inlining of Static Final Variables
What Does the Registernatives() Method Do
How to Create a Folder in Java
What Is the Purpose of the Java Constant Pool
How to See the Source Code of the Sun Jdk
Which Artifacts Should I Use for Jaxb Ri in My Maven Project