I have a strange issue with HashMap.
There are multiple threads that accessing same hashmap (not threadsafe).
Sometime, the process gets stuck.
when I inspect the thread stack, i see many threads in state:
java.lang.Thread.State: RUNNABLE
at java.util.HashMap.get(HashMap.java:303)
Note this happens very rare. And can't be reproduced on demand.
Why it gets stuck?
There is no synchronization on hashmap.
keys are strings
What's wrong using HashMap in multithreaded environment? When get() method go to infinite loop? It is a bug to have multiple threads use a non-synchronized collection (really any mutable class) in an unprotected manner. Certain if each thread had their own HashMap instance then this is not an issue.
Situation: The default capacity of HashMap is 16 and Load factor is 0.75, which means HashMap will double its capacity when 12th Key-Value pair enters in the map (16 * 0.75 = 12). When 2 thread tries to access HashMap simultaneously, then you may encounter infinite loop.
The HashMap is non-thread-safe and can not be used in a Concurrent multi-threaded environment. Comparatively, ConcurrentHashMap is a thread-safe and specially designed for use in multi-threaded and Concurrent environment.
There are multiple threads that accessing same hashmap (not threadsafe).
Sounds like you are using this HashMap
in a threaded environment without proper synchronization. You are hitting a problem where the HashMap
memory is corrupted and a thread is most likely spinning because of this. You cannot update an unsynchronized map and read from it using multiple threads. In some situations you can build a read-only map and then share it without synchronization in multiple threads.
I would suggest switching to use ConcurrentHashMap
instead or wrap your HashMap
with Collections.synchronizedMap(...)
.
To elaborate more, the issue here is two fold. You cannot have two threads updating an unsynchronized map because of race conditions when altering internal map data. Locking is necessary to ensure mutex and proper data synchronization. One thread might make changes not seen by the other thread which could overwrite them.
The other issue is memory synchronization. If one thread updates the HashMap
in its memory, other threads won't necessarily get the same view of the map's storage. This isn't a problem until a thread gets partial memory update -- where some of the HashMap
memory has been updated and other portions have not. You might, for example, get a portion of the bucket array or a portion of the bucket storage which when traversed causes the thread to spin.
One of the main reasons multi-processor boxes run threaded code faster is that the threads can use per-processor cached memory. The cached memory is the problem. One processor could be reading or changing its cached memory at the same time another processor is doing the same. Synchronizing local cached memory with central storage is one of things you need to worry about and the reasons why synchronization is so important.
If you are using a pre-populated HashMap
that is only going to be read by your threads and never updated then it may be ok. I depends highly on how each of the threads got the reference to the new HashMap
. If the HashMap
was constructed and then populated and passed into the threads via their constructor (or before they were started) then you are good. However if the threads are already running then it depends on how they get a reference to the map. They may still get a partial copy of the map's memory depending on the circumstances and your memory architecture.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With