5

First, I'll describe what I want and then I'll elaborate on the possibilities I am considering. I don't know which is the best so I want some help.

I have a hash map on which I do read and write operations from a Servlet. Now, since this Servlet is on Tomcat, I need the hash map to be thread safe. Basically, when it is being written to, nothing else should write to it and nothing should be able to read it as well.

I have seen ConcurrentHashMap but noticed its get method is not thread-safe. Then, I have seen locks and something called synchronized.

I want to know which is the most reliable way to do it.

jmj
  • 237,923
  • 42
  • 401
  • 438
pratnala
  • 3,723
  • 7
  • 35
  • 58
  • 9
    In what way is ConcurrentHashMap.get not threadsafe? And what level of granularity are you looking for? By "when it is being written to" do you mean that there will be *multiple* put operations, or is it sufficient for each one to be atomic? – Jon Skeet Aug 01 '13 at 16:56
  • Seeing the API doc, I thought it is not thread safe. There can be multiple put operations to the hash map if say 3 people decide to do the same put operation. – pratnala Aug 01 '13 at 17:11
  • 2
    @pratnala The fact that it allows concurrent operations does not make it not thread safe. – assylias Aug 01 '13 at 17:12
  • Also, if something is being written to the hash map, somebody else shouldn't be able to read it. Does ConcurrentHashMap guarantee that? – pratnala Aug 01 '13 at 17:26
  • 1
    It does not guarantee that, from the javadoc: 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. – Alper Akture Aug 01 '13 at 20:44
  • I can't fathom what I was thinking and why I needed this specific condition (no reads or writes during a write) when I asked this. That too, for a class assignment. Don't use coarse grained locks, kids! – pratnala Nov 14 '18 at 07:06

5 Answers5

19

ConcurrentHashMap.get() is thread safe.

You can make HashMap thread safe by wrapping it with Collections.synchronizedMap().

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
4

EDIT: removed false information

In any case, the synchronized keyword is a safe bet. It blocks any threads from accessing the object while inside a synchronized block.

// Anything can modify map at this point, making it not thread safe
map.get(0);

as opposed to

// Nothing can modify map until the synchronized block is complete
synchronized(map) {
    map.get(0);
}
Deactivator2
  • 311
  • 1
  • 10
  • There is only ever one instance of each `Servlet` in a container. All mapped requests will go through the same instance. If you have instance fields, then each request will have access to them. – Sotirios Delimanolis Aug 01 '13 at 17:05
  • Requests get executed in different threads i.e. `service()` method of servlets could get executed concurrently (unless Servlet is declared as `SingleThreadModel`) although there is a single instance of a servlet. Hence, instance variable declared in a Servlet class could be invoked from multiple request processing threads. – Bimalesh Jha Aug 01 '13 at 17:07
  • Ack. You're (both) right, I don't know what I was thinking. I thought we (at work) had disproved this with a number of tests. I'll remove that part of my answer. – Deactivator2 Aug 01 '13 at 17:10
3

Collections.synchronizedMap(new HashMap<K, V>);

Returns a synchronized (thread-safe) map backed by the specified map. In order to guarantee serial access, it is critical that all access to the backing map is accomplished through the returned map.

It is imperative that the user manually synchronize on the returned map when iterating over any of its collection views:

Community
  • 1
  • 1
jmj
  • 237,923
  • 42
  • 401
  • 438
  • What do you mean by "it is critical that all access to the backing sorted map is accomplished through the returned sorted map"? – pratnala Aug 01 '13 at 17:13
  • copied description of Collection.synchronizedSortedMap() by mistake, by that i meant that the map you passed in still would not be threadsafe – jmj Aug 01 '13 at 17:15
  • I still don't understand the description. – pratnala Aug 01 '13 at 17:36
3

I would like to suggest you to go with ConcurrentHashMap , the requirement that you have mentioned above ,earlier I also had the same type of requirement for our application but we were little more focused on the performance side.

I ran both ConcurrentHashMap and map returned by Colecctions.synchronizedMap(); , under various types of load and launching multiple threads at a time using JMeter and I monitored them using JProfiler .After all these tests we came to conclusion that that map returned by Colecctions.synchronizedMap() was not as efficient in terms of performance in comaprison to ConcurrentHashMap.

I have written a post also on the same about my experience with both.

Thanks

saurav
  • 3,424
  • 1
  • 22
  • 33
0

This is the point of ConcurrentHashMap class. It protects your collection, when you have more than 1 thread.

alexca
  • 57
  • 7