Aldian Aldian - 6 months ago 50
Java Question

Skip synchronization when iterating over a LinkedHashSet and no remove is done?

I have to iterate on a Set which is shared among multiple threads. Something like this code:

class MyObj{}
final static Set<MyObj> instances = Collections.synchronizedSet(new LinkedHashSet<MyObj>());
// returns the same object from the set if any, or add it if not found
public MyObj test2(MyObj a){

return a;

for(MyObj o : instances){
return o;

throw new IllegalStateException("Impossible to reach this line");

I have read the javadoc for synchronizedSet, it states that:

It is imperative that the user manually synchronize on the returned
set when iterating over it:

Set s = Collections.synchronizedSet(new HashSet());
... synchronized (s) {
Iterator i = s.iterator(); // Must be in the synchronized block
while (i.hasNext())

Failure to follow this advice may result in non-deterministic behavior.

But, I also read on this answer that LinkedHashSet provides insertion-ordered iteration. And all a thread will do with my Set is

  • trying to add one new object

  • in case the add operation returns false, iterate over it to test the objects

  • never perform a clear or remove, the set can only grow.

With all these hypothesis, my guess is that I don't need to perform synchronization on the Set since even if another thread adds a new object while I am iterating over it, it will be at the end of the set and I will find the object I am looking for before reaching the insertion point.

Is this correct?


No, you must synchronize, as stated in the Javadoc:

Note that this implementation is not synchronized. If multiple threads access a linked hash set concurrently, and at least one of the threads modifies the set, it must be synchronized externally.

If you have one thread iterating the set when another adds an element to it, you will get a ConcurrentModificationException.

The iterators returned by this class's iterator method are fail-fast: if the set is modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a ConcurrentModificationException.