Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HashSet and multithreading

I work on Java 7.

I want to know if the method contains is thread-safe on HashSet object.

The HashSet is initialized by one thread. Then we wrap the HashSet with unmodifiable collection (Collections.unmodifiableSet). After initialization, multiple threads call only the method contains.

When I read the Javadoc, it's unclear for me.

On HashSet Javadoc we can read

This class implements the Set interface, backed by a hash table (actually a HashMap instance).

...

Note that this implementation is not synchronized.

And on the HashMap Javadoc, we can read:

Note that this implementation is not synchronized. If multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with a key that an instance already contains is not a structural modification.)

For me, this means the method contains is not a structural modification.

So multiple call to the method contains is it thread-safe?

If it's true: Is it guaranteed on all implementation of JVM (like IBM JVM)?

like image 325
lecogiteur Avatar asked Feb 18 '17 09:02

lecogiteur


1 Answers

In general, there can be no concurrency race (and thus conflict) solely between read operations. Concurrency problems arise between read and write operations. So, multiple read operations interleaved are always thread-safe (if we assume that such a notion of thread-safety is well defined).

Now, there is one more case where there might be a concurrency issue and this is during the initialisation of the data structure, since this can be considered the only modification (write operation) in your case. In order to make sure that all the subsequent contains() invocations will see the fully initialised Set, you have to make sure that it's correctly initialised. This concept is defined as "safe-publication" in Java and you can read more about it here or in the book "Java Concurrency in Practice" book.

To conclude, Collections.unmodifiableSet() publishes the result in a safe way through a final field. So, yes you can be sure that all contains() will see the fully initialised Set

like image 106
Dimos Avatar answered Oct 19 '22 15:10

Dimos