2

In ConcurrentHashMap there is concept of segmentation. What it means if two threads are trying to access ConcurrentHashMap they it gets divided in two blocks and default size of blocks is 16.

Now suppose in a scenario where ConcurrentHashMap has only two elements and two different threads comes and thread1 tries to modify first value and thread2 tries to modify second value. In this case whether ConcurrentHashMap will go for segmentation?

Now in a different scenario both the threads try to modify same value how ConcurrentHashMap will handle this situation? By using locking mechanism or is there something else ?

GD_Java
  • 1,359
  • 6
  • 24
  • 42
  • 2
    You need to define "modify a value". The hashmap could not care less about changing properties on its values and does not interact with that at all, please show example code. – Affe Apr 09 '13 at 18:17

3 Answers3

4

ConcurrentHashMap has several buckets. Keys are mapped, based on their hash value, into one of the buckets. When you add or retrieve a value, the bucket associated with that key is locked.

In the case of your first question, there are two possibilities: either both keys live in the same bucket, or they live in different buckets. In the first case, only one thread can work at a time -- the first one to acquire the lock will grab it and work, the second thread will wait its turn. In the second case, where the keys are in different buckets, they'll each acquire independent locks and do their work concurrently.

For your second question, it is the bucket that gets locked, and nothing else. If two threads try to store two values for the same key, then ConcurrentHashMap promises that one of the two values will be associated with the key. i.e. if thread A runs map.put("Answers",2); and thread B runs map.put("Answers",10);, then ConcurrentHashMap will ensure that the map is valid and contains either 2 or 10 for "Answers", but it won't make any promises about which of those two it is.

Nathaniel Waisbrot
  • 23,261
  • 7
  • 71
  • 99
  • In java; all assignments of references is [atomic by nature.](http://stackoverflow.com/questions/4756536/what-operations-in-java-are-considered-atomic) So if two threads are trying to change the value of same key; by default that will be atomic right? Then why we need CHM or Lock in this case? – Kanagavelu Sugumar Mar 29 '16 at 10:04
  • 2
    Because `put` does more than simple assignment: it might need to allocate space and it keeps a counter of how many entries it has. Take a look at the code (old link but still relevant): http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/ConcurrentHashMap.java#447 – Nathaniel Waisbrot Mar 29 '16 at 15:04
  • PlusOne! Thank you! Got it. – Kanagavelu Sugumar Mar 29 '16 at 17:08
3

CHM guarantees that those operations (e.g. put, putIfAbsent, etc.) won't overlap, and yes, that's done with locking. Each segment of the CHM has its own lock that gets taken whenever you're modifying that segment.

(For reference, as @Affe pointed out, if you're modifying the contents of a value in the ConcurrentHashMap, CHM doesn't do -- can't do -- anything to make that thread safe.)

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
0

First of all , new implementation of CHM doesn't use Segments at all, it still uses array of nodes, if node in given index doesn't exist and two threads are trying to insert two entries with hashcode that equals to given index then CHM uses CAS , otherwise if node exists then CHM uses lock on the first element of this node to put new value. Reads in CHM are non blocking and use happen before guarantee with the help of atomic reads from Unsafe class. Check out my blog about CHM for more details https://strogiyotec.github.io/pages/posts/chm.html

Almas Abdrazak
  • 3,209
  • 5
  • 36
  • 80