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){
if(instances.add(a))
return a;
for(MyObj o : instances){
if(o.equals(a))
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()) foo(i.next()); }
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?