ConcurrentHashMap 是 一种线程安全的HashMap,关于HashMap的可以看前面两篇总结,如果是用HashTable和或者是Collections.SynchronizedMap 来实现线程安全的hash式存储功能的话,都会有一个问题,他们都会整个集合加锁,造成线程对这个数据结构的其他操作的阻塞 , ConcurrentHashMap就是为了并发和性能而产生的
ConcurrentHashMap 和 之前介绍的HashMap关键的区别在于Segment。
-
Segment本身就相当于一个HashMap对象。
-
Segment包含一个HashEntry数组,数组中的每一个HashEntry既是一个键值对,也是一个链表的头节点。
-
在ConcurrentHashMap集合中有多少个呢?有2的N次方个,共同保存在一个名为segments的数组当中。
-
可以说,ConcurrentHashMap是一个二级哈希表。在一个总的哈希表下面,有若干个子哈希表。

每个Segment的读写操作都高度分离,每个Segment都持有一把锁,两个线程对同一个Segment做写操作时候要获取锁,会造成阻塞,在保证线程安全的同时降低了锁的粒度,让并发操作效率更高。
###Get方法:
1.为输入的Key做Hash运算,得到hash值。 2.通过hash值,定位到对应的Segment对象 3.再次通过hash值,定位到Segment当中数组的具体位置。
###Put方法:
1.为输入的Key做Hash运算,得到hash值。 2.通过hash值,定位到对应的Segment对象 3.获取可重入锁 4.再次通过hash值,定位到Segment当中数组的具体位置。 5.插入或覆盖HashEntry对象。 6.释放锁。
####Size方法(防止求Size的时候插入新的数据) ConcurrentHashMap的Size方法是一个嵌套循环,大体逻辑如下:
1.遍历所有的Segment。 2.把Segment的元素数量累加起来。 3.把Segment的修改次数累加起来。 4.判断所有Segment的总修改次数是否大于上一次的总修改次数。如果大于,说明统计过程中有修改,重新统计,尝试次数+1;如果不是。说明没有修改,统计结束。 5.如果尝试次数超过阈值,则对每一个Segment加锁,再重新统计。 6.再次判断所有Segment的总修改次数是否大于上一次的总修改次数。由于已经加锁,次数一定和上次相等。 7.释放锁,统计结束。
源码还是要回头看。。。