Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is setting a HashMap thread safe?

I have a HashMap in my program which is accessed by multiple threads, and is occasionally set by a single thread.

For example:

Map<String, String> myMap = new HashMap<String, String>();

This is accessed by multiple threads. Once an hour, a single thread calls:

myMap = myRefreshedVersionOfTheMap;

So my question is whether or not this is thread safe. If both maps always have the key "importantKey", is it possible for a reading thread to ever access the map at a time when "importantKey" does not exist?

Edit:

Thanks to the answers, I've realized this question is actually independent of the HashMap. It was more a question about object reference assignment.

like image 327
CorayThan Avatar asked Jun 20 '13 17:06

CorayThan


People also ask

Is it thread safe to refresh a hashmap?

First off, Java's HashMap class is not thread safe, so there are no guarantees when reads and writes are happening concurrently. However, since reads and writes to references in Java are atomic, then the pattern you described could be thread-safe as long as the refresh code is not mutating the old map.

Is hashtable thread safe in Java?

Unlike the new collection implementations, Hashtable is synchronized. If a thread-safe implementation is not needed, it is recommended to use HashMap in place of Hashtable, says the javadoc about Hashtable. Same, if you need a thread-safe ArrayList one day, use Vector.

Is map a thread safe variable?

For example when we create a map as a local variable of a method, we are assured that the map instance is accessed in a thread safe way as each thread has its own execution stack during a method invocation. When the map is a field of the class, synchronization may be needed or at least we could wonder if it is.

What happens if a hashmap is updated without synchronization?

A HashMapthat is updated without synchronization will break evenif the threads are using disjoint sets of keys. Here are just some1of the things that can go wrong. If one thread does a put, then another thread may see a stale value for the hashmap's size.


2 Answers

This is not thread safe. Even though there are no writes to the map itself after the point of publication (from the point of view of the thread doing the publication), and reference assignment is atomic, the new Map<> has not been safely published. It particular, there are writes to the Map during its construction - either in the constructor, or after, depending on how you add those elements, and those writes may or may not be seen by other threads, since even though they intuitively occur before the map is published to the other threads, this isn't formally the case according to the memory model.

For an object to be safely published, it must be communicated to the outside world using some mechanism that either establishes a happens-before relationship between the object construction, the reference publication and the reference read, or it must use a handful of narrower methods which are guaranteed to be safe for publishing:

  • Initializing an object reference from a static initializer.
  • Storing a reference to it into a final field.

Your idiom would be safe if you declared myMap volatile. More details on safe publication can be found in JCIP (highly recommended), or here, or in this longer answer on a similar topic.

like image 110
BeeOnRope Avatar answered Oct 10 '22 11:10

BeeOnRope


If you mean you are creating an entirely new Map and are assigning it to myMap which is what the other threads are accessing, then yes. Reference assignment is atomic. It's threadsafe because you are not modifying the contents of a Map while other threads are reading from it - you just have multiple threads reading from a Map.

You just need to declare it volatile so other threads don't cache it.

like image 9
Brian Roach Avatar answered Oct 10 '22 10:10

Brian Roach