Reputation: 23002
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 ?Upvotes: 0
Views: 2659
Reputation: 22442
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)
Upvotes: 7