Are final unmodifiable sets thread safe?

collections, java, thread-safety

Solution

If it's an unmodifiable `Set<String>`, as per your example, then you're fine; because `String` objects are immutable. But if it's a set of something that's not immutable, you have to be careful about two threads both trying to change the same object inside the set.

You also have to be careful about whether there's a reference somewhere to the `Set`, that's not unmodifiable. It's possible for a variable to be unmodifiable, but still be referring to a `Set` which can be modified via a different variable; but your example seems to have that covered.

Problem

The javadocs are not clear about this: are unmodifiable sets thread safe? Or should I worry about internal state concurrency problems? ``` Set<String> originalSet = new HashSet<>(); originalSet.add("Will"); originalSet.add("this"); originalSet.add("be"); originalSet.add("thread"); originalSet.add("safe?"); final Set<String> unmodifiableSet = Collections.unmodifiableSet(originalSet); originalSet = null; // no other references to the originalSet // Can unmodifiableSet be shared among several threads? ``` I have stumbled upon a piece of code with a static, read-only `Set` being shared against multiple threads... The original author wrote something like this: ``` mySet = Collections.synchronizedSet(Collections.unmodifiableSet(originalSet)); ``` And then every thread access it with code such as: ``` synchronized (mySet) { // Iterate and read operations } ``` By this logic only one thread can operate on the Set at once... So my question is, for a unmodifiable set, when using operations such as for each, `contains`, `size`, etc, do I really need to synchronize access?

Original source