0

If my requirements dictate that most of my accesses to the list are for reading and modifications if any are going to be minimal, why can't I just do either of the following

  1. synchronize modifyList method and use ArrayList. All reads from arraylist will be unsynchronized or
  2. inside modifyList, do a Collections.synchronizedList(arrayList) or
  3. CopyOnWriteArrayList (not sure what it buys here)

Why would I use either ? which is better ?

treefrog
  • 1,027
  • 1
  • 15
  • 30

2 Answers2

4

For 1 & 2, I'm not sure what you're trying to accomplish by only synchronizing writes. If there are potential readers who might be iterating the list, or who are looking things up by index, then only synchronizing writes proves nothing. The readers will still be able to read while writes are in progress and may see dirty data or get exceptions (ConcurrentModification or IndexOutOfBounds.)

You would need to synchronize both your reads and writes if you want 'safe' iterating and getting while other threads make changes. At which point, you may as well have just used a Vector.

CopyOnWriteArrayList is purpose built for what you want to do. It buys safe synchronization-free iterators, while substantially increasing the cost of writes. It also had the advantage of doing what you want (or what it seems you want from the terse question :) ), entirely encapsulated within the JavaSE API, which reduces 'surprise' for future developers.

(do note that if you have multi-step processes involving reads with 'get' even using CopyOnWriteArrayList may not be entirely safe. You need to evaluate what your code actually does and if an interleaving modification would break the method that is getting.)

Affe
  • 47,174
  • 11
  • 83
  • 83
  • You shouldn't be recommending `Vector`: http://stackoverflow.com/questions/1386275/why-is-java-vector-class-considered-obsolete-or-deprecated – LanguagesNamedAfterCofee Sep 29 '12 at 20:21
  • Don't see that as a recommendation really. It's a sarcastic quip. "If you're not careful to do it right, you're not better off than just using Vector, which we all know is a deprecated poor choice." /shrug – Affe Sep 29 '12 at 20:34
2

Another solution would be to use ReentrantReadWriteLock so you can use read-only locks on read operations (which don't block other reads) and a write lock for when you're writing (which will block until there are no reads, and won't allow any read locks until it's released.

Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
  • I suppose this would be a better solution if my list is really large ? – treefrog Jan 17 '11 at 21:09
  • Well, it has the disadvantage that if there are a lot of readers, your write might block for a while until they all go away. But it has similar advantages to CopyOnWriteArrayList when everybody hitting it is reading and not writing. – Paul Tomblin Jan 17 '11 at 21:57