Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread-safe iteration over a collection

We all know when using Collections.synchronizedXXX (e.g. synchronizedSet()) we get a synchronized "view" of the underlying collection.

However, the document of these wrapper generation methods states that we have to explicitly synchronize on the collection when iterating of the collections using an iterator.

Which option do you choose to solve this problem?

I can only see the following approaches:

  1. Do it as the documentation states: synchronize on the collection
  2. Clone the collection before calling iterator()
  3. Use a collection which iterator is thread-safe (I am only aware of CopyOnWriteArrayList/Set)

And as a bonus question: when using a synchronized view - is the use of foreach/Iterable thread-safe?

like image 747
MRalwasser Avatar asked Dec 23 '10 10:12

MRalwasser


2 Answers

You've already answered your bonus question really: no, using an enhanced for loop isn't safe - because it uses an iterator.

As for which is the most appropriate approach - it really depends on how your context:

  • Are writes very infrequent? If so, CopyOnWriteArrayList may be most appropriate.
  • Is the collection reasonably small, and the iteration quick? (i.e. you're not doing much work in the loop) If so, synchronizing may well be fine - especially if this doesn't happen too often (i.e. you won't have much contention for the collection).
  • If you're doing a lot of work and don't want to block other threads working at the same time, the hit of cloning the collection may well be acceptable.
like image 62
Jon Skeet Avatar answered Sep 19 '22 11:09

Jon Skeet


Depends on your access model. If you have low concurrency and frequent writes, 1 will have the best performance. If you have high concurrency with and infrequent writes, 3 will have the best performance. Option 2 is going to perform badly in almost all cases.

foreach calls iterator(), so exactly the same things apply.

like image 30
OrangeDog Avatar answered Sep 17 '22 11:09

OrangeDog