I have following case,
public class Test {
private static final int MAX_NUMBER = 10_00_00;
public static void main(String[] args) {
List<Integer> list = new CopyOnWriteArrayList<>();
long start = System.nanoTime();
for(int i = 0; i < MAX_NUMBER; i++) {
list.add(i * 2);
}
long end = System.nanoTime();
System.out.println(((end - start) / Math.pow(10, 9)));
}
}
OUTPUT
6.861539857
It adds element quite slowly compared to ArrayList
which took approximately 0.004690843
. I came to know the reason in the documentation,
A thread-safe variant of
ArrayList
in which all mutative operations (add, set, and so on) are implemented by making a fresh copy of the underlying array.
So, my understanding is, whenever I add new element in this list it will create new fresh array and add element at last index of this array. I find a lock in add
method and apart from that that method is actually creating new array every time.
When I increased MAX_NUMBER
to 10_00_000
my programs keeps on running and never end (it would but I can't wait for so long).
I think Collections.synchronizedList
is the better choice when you want thread safety with speed. I used it and it took about 0.007673728
.
My questions :
MAX_NUMBER = 10_00_000
? (as it took about 6 seconds with MAX_NUMBER = 10_00_00
) Is this happening because mutative operation creates new array every time ? CopyOnWriteArrayList
has performance drawback when you have huge number of elements and better to choose something else (i.e. Collections.synchronizedList
)?CopyOnWriteArrayList
in public APIs ? Is there any drawbacks other than this ?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)