Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java hash map thread visibility

I am fully loading a java HashMap on initialization, but after initialization multiple threads will be reading the data from the HashMap. i'd like to avoid any type of synchronization since the map is essentially read only and never changes. But can i guarantee that all keys and values are visible to all threads?

like image 376
richs Avatar asked Mar 02 '11 14:03

richs


People also ask

Is HashMap in Java thread-safe?

Java HashMap is not thread-safe and hence it should not be used in multithreaded applications.

Can multiple threads access HashMap?

— Hashmap can solve performance issue by giving parallel access to multiple threads reading hashmap simultaneously. But Hashmap is not thread safe, so what will happen if one thread tries to put data and requires Rehashing and at same time other thread tries to read data from Hashmap, It will go in infinite loop.

Is Map Get thread-safe Java?

Overview. Maps are naturally one of the most widely style of Java collection. And, importantly, HashMap is not a thread-safe implementation, while Hashtable does provide thread-safety by synchronizing operations. Even though Hashtable is thread safe, it is not very efficient.


2 Answers

If the map's contents never change then you don't have a problem. Memory model visibility problems come into play only when the contents of a variable change.

You will likely want to synchronize the initialization of the map both to make sure no threads access it before it's fully initialized, and to make sure that the values loaded into the map are all visible.

EDIT: Originally I totally ignored the issue of how the map gets initialized in the first place. After reading one of the Pugh articles (again) it seems like the map really needs to be final in order for the initialization-data to become visible:

The ability to see the correctly constructed value for the field is nice, but if the field itself is a reference, then you also want your code to see the up to date values for the object (or array) to which it points. If your field is a final field, this is also guaranteed. So, you can have a final pointer to an array and not have to worry about other threads seeing the correct values for the array reference, but incorrect values for the contents of the array. Again, by "correct" here, we mean "up to date as of the end of the object's constructor", not "the latest value available".

There is a list of conditions that force a 'happens-before' relationship, given in the Java spec, I should quote them here (or if somebody else does in their answer I will vote for it). The static variable and Holder idiom is certainly one way to go. The question is pretty broad as it doesn't specify how the map gets initialized, if you post a question describing how you propose to do the initialization you will likely get a more directly helpful answer.

like image 187
Nathan Hughes Avatar answered Oct 05 '22 23:10

Nathan Hughes


If you have the HashMap declared as final, and you pre-initialize a local HashMap then store the global HashMap with the local, after constructor initialization that HashMap's contents are garunteed to be visibile.

Final fields must be used correctly to provide a guarantee of immutability. An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object’s final fields.

http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf

like image 20
John Vint Avatar answered Oct 06 '22 00:10

John Vint