Working with collections in a multi-thread
application is a challenge. Just imagine the list which is accessible by a few
threads and every thread is seeking for a chance to change the list data,
that’s a typical showcase of the ConcurrentModificationException. In order to
get rid of this and other problems JDK (since version 1.5) provides improved
mechanisms for storing ‘Iterable’ data in multithread application.
This article is an overview of widely used
concurrent collection such as CopyOnWriteArrayList
The
name of the collection is very straightforward, every ‘write’ operation (add,
remove, set) causes the copying and creation of the modified collection. It
allows us to prevent ConcurrentModificationException as long as every thread’s
iterator will have its own copy of the collection. The official Oracle
documentation names such iterators as “snapshot” style iterator; this iterator
“uses a reference to the state of the array at the point that the iterator was
created”
This is the add operation for
CopyOnWriteArrayList
public boolean add(E e) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len + 1); newElements[len] = e; setArray(newElements); return true; } finally { lock.unlock(); } }
Every time you modify collection the new
copy of the whole collection is created – it’s quite expensive operation and
that’s why it’s not recommended to use CopyOnWriteArrayList for frequently
modified data. Another interesting method from the listing is setArray(newElements); it updates actual
array and every new thread’s iterator will have updated version of the array –
other thread iterators (which run in parallel) won’t be affected using their
own local copies of the array.
Question: two or more threads modify the
CopyOnArrayList simultaneously, what will be the result of their job?