views:

29

answers:

2

I've Lists and Maps in my WebAppContext.
Most of the time these are only read by multiple Threads but sometimes there's the need to update or add some data.
I'm wondering what's the best way to do this without incurring in a ConcurrentModificationException.

I think that using CopyOnWriteArrayList I can achieve what I want in terms of
- I do not have to sync on every read operation
- I can safety update the list while other threads are reading it.

Is this the best solution? What about Maps?

+1  A: 

CopyOnWriteArrayList should work for what you want as a List. For a Map, you may want to look at ConcurrentHashMap, unless you need a SortedMap, in which case ConcurrentSkipListMap would be better.

The only problem I see with ConcurrentHashMap is that its iterators are still only intended to be accessed by one thread at a time even though they won't throw ConcurrentModificationException.

R. Bemrose
+1  A: 

You want to be careful when using a CopyOnWriteArrayList. The typical collection (on a very broad scale) is 80% reads 19% writes and 1% remove. CopyOnWriteArraylist performs poorly under those conditions. The best use of a CopyOnWriteArrayList is when the reads are ~90-95%. Writing too much will degrade performance alot (the class throws an UnsupportedOperationException when calling compareTo because a Collections.sort on it is terrible).

Basically, if you are doing ALOT of reads and few writes the a CopyOnWriteArrayList is fantastic, though if youre not, you can consider Collections.synchronizedList. If you want to ensure non blocking reads then obviously CopyOnWriteArrayList would fit.

ConcurrentHashMap is great as a replacement for any map implementation you have (unsorted at least). It will not block on reads, and block only specific buckets on writes, so is very fast.

John V.