Using HashMap in a multi-threaded environment

I was interviewed on JavaRevisited and I had difficulty understanding this question:

What's wrong with using HashMap in a multi-threaded environment? When does the get () method enter an infinite loop?

In my opinion, using a HashMap in a multi-threaded environment is not a problem if our application does not access / read the threads that modify the created HashMap , and not just access the HashMap.

So, in my opinion, there are no problems, because in the application we just access the HashMap in a multi-threaded environment.

Please let me know if my understanding is correct.

+5
source share
4 answers

What's wrong with using HashMap in a multi-threaded environment? When does the get () method go into an infinite loop?

What's wrong is that multiple threads use an unsynchronized collection (in fact any mutable class) in an insecure manner. Of course, if each thread had its own instance of HashMap this is not a problem. This is a problem if multiple threads are added to the same HashMap instance without being synchronized . Even if only one HashMap stream and other streams read from the same card without synchronization, you will run into problems.

If you need to use the same hash table object in multiple threads, you should consider using ConcurrentHashMap , wrapping each of the HashMap calls in a synchronized {} block, or using Collections.synchronizedMap(new HashMap<...>()) to build.

get() goes into an infinite loop because one of the threads has only a partially updated representation of the HashMap in memory and there must be some kind of pointer loop. This is the danger of using an unsynchronized collection with multiple threads.

So, as I understand it, this is not a problem if in an application we just access HashMap in a multi-threaded environment?

If by "access" you mean "reading", then this is true for qualifications . You must make sure:

  • All HashMap updates complete before stream instances are created, and the stream that creates the map also branches the streams.
  • Streams use HashMap in read-only mode ( get() or iterate without deleting)
  • No themes updating the map

If any of these conditions are not met, you will need to use a synchronized card instead.

+19
source
+3
source

This is a classic question. ArrayList and HashMap are not synchronized, while Vector and HashTable. Therefore, you should use a HashTable if you do not define mutexes very carefully.

In other words, methods, for example. HashTable ensures that no other thread will work with HashTable at any given time. If you use a HashMap, you will have to do it manually, making sure that you synchronize the HashMap before calling the method.

Update: @Gray statement. It seems like wrapping a HashMap with Collections.synchronizedMap (new HashMap ()) is the way to go.

EDIT: The other posters answered better than me. My answer, however, sparked an interesting discussion about using the soon obsolete Vector, Stack, Hashtable, and Dictionary classes, so I leave the question here as a chapter for the comments below. Thanks guys!

+1
source

I assume that they are intended to access a shared copy of the HashMap . Shared mutable state .

Since it is not synchronized , each thread will grab its copy from main memory, modify and overwrite it.

 HashMap with one entry <n, 1> thread 1 grab the copy thread 2 grab the copy thread 1 modify <n, 2> thread 2 modify <n, 3> thread 1 is done, and stores the copy in the main memory now memory is <n, 2> thread 2 is done and stores the copy now memory is <n, 3> The state thread 1 is lost 
0
source

All Articles