Our legacy multi-threaded application has a lots of usage of Hashtable. Is it safe to replace the Hashtable instances with ConcurrentHashmap instances for performance gain? Will there be any side effect?
-
1Some subtle differences: http://stackoverflow.com/questions/12646404/concurrenthashmap-and-hashtable-in-java – christopher Apr 19 '16 at 14:45
-
This performance comparison of HashMap vs ConcurrentHashMap might be useful http://stackoverflow.com/questions/1378310/performance-concurrenthashmap-vs-hashmap – GuiSim Apr 19 '16 at 14:46
-
Is there a similar comparison between Hashtable and ConcurrentHashmap performance? – dpkp Apr 19 '16 at 14:54
-
You could just try it but I'd assume ConcurrentHashmap yields higher performance since it synchronizes far less than Hashtable (e.g. ConcurrentHashMap only synchronizes if you put two elements into the same bucket while Hashtable synchronizes every put operation) – Thomas Apr 19 '16 at 14:58
2 Answers
Is it safe to replace the Hashtable instances with ConcurrentHashmap instances for performance gain?
In most cases it should be safe and yield better performance. The effort on changing depends on whether you used the Map
interface or Hashtable
directly.
Will there be any side effect?
There might be side effects if your application expects to immediately be able to access elements that were put into the map by another thread.
From the JavaDoc on ConcurrentHashMap:
Retrieval operations (including get) generally do not block, so may overlap
with update operations (including put and remove). Retrievals reflect the
results of the most recently completed update operations holding upon their onset.
Edit: to clarify on "immediately" consider thread 1 adds element A to the map and while that write is executed thread 2 tries to whether A exists in the map. With Hashtable
thread 2 would be blocked until after the write so the check would return true but when using ConcurrentHashMap
it would return false since thread 2 would not be blocked and the write operation is not yet completed (thus thread 2 would see an outdated version of the bucket).

- 87,414
- 12
- 119
- 157
-
1"...if your application expects to immediately be able to access elements that were put into the map by another thread." This assumes some common understanding for *immediately* which is an unclear term in the concurrency world. It also seems to imply that `ConcurrentHashMap` does not offer some timely guarantee that is offered by `Hashtable`, but that is not the case. – Dimitar Dimitrov Apr 19 '16 at 15:42
-
@DimitarDimitrov that's why I said there _might_ be side effects. What I mean is that if one thread puts something into the map and another thread reads it at almost the same moment (write operation is not finished when read operation starts) you can't expect to get the new value in the read operation's results when using a ConcurrentHashMap but due to the synchronization in Hashtable you're guaranteed to get it. After all that might not be relevant but it's a possible side effect. – Thomas Apr 19 '16 at 15:57
-
That's an intuitive answer, but I'd label it as incorrect, as it instills a wrong idea about the guarantees. You cannot rely on the chance that your `get()` thread will be parked and some time later will see the last `put` it synchronized with. You should be able to handle the case where your `get()` obtained the lock before that same `put()`, and if you already do that, you are better off with a `ConcurrentHashMap`, because you get all the same guarantees but with almost always faster performance as an addition. – Dimitar Dimitrov Apr 19 '16 at 16:10
-
Thanks for the details. So with ConcurrentHashmap stale data reading is possible. In short data consistency in the system may not be guaranteed? – dpkp Apr 19 '16 at 16:15
-
-
Is there a use case where `HashTable` is preferable over `ConcurrentHashmap`? – IgorGanapolsky Mar 24 '17 at 19:16
-
1@IgorGanapolsky The JavaDoc `ConcurrentHashMap` states: "Retrieval operations generally do not block, so may overlap with update operations". That means that a reading thread might not see an update until it is completed, i.e. you get some sort of "eventual" consistency. If you don't want that behavior, i.e. you want all reads that are started after an update is been initiated to see the result of that update you'd need to synchronize reads and writes and in that case using a `Hashtable` might be preferable. – Thomas Mar 27 '17 at 13:59
Depending on the size of your Hashtable
objects you might get some performance gains by switching to ConcurrentHashmap
.
ConcurrentHashmap
is broken into segments which allow for the table to be only partially locked. This means that you can get more accesses per second than a Hashtable
, which requires that you lock the entire table.
The tables themselves are both thread safe and both implement the Map interface, so replacement should be relatively easy.

- 21,558
- 8
- 41
- 88