题目来源:https://zhuanlan.zhihu.com/p/86536581
**java基础 **
02 concurrentHashMap,段锁,如何分段,和hashmap在hash上的区别,性能,等等
-
concurrentHashMap
由于hashMap在处理高并发的问题时,会出现因put操作,扩容混乱时出现的链路环,有可能造成下一次操作的死锁。为了解决这个问题提出了:concurrentHashMap。 -
段锁(segments)如何分段
在concurrentHashMap中,对哈希表进行了分segment的操作,并且segment的个数是2的次幂。使得整个哈希表相当于一个二级哈希表。在并发过程中,segment之间相互独立,读写操作互不影响。
不同segment之间的读写:并发执行
同一segment中的读写:并发执行
同一segment中的写写:会进行加锁 -
如何统计当前concurrentHashMap的个数
- 累计统计每一个segment的个数,同时统计修改的次数
- 当修改的次数未比上一次统计的修改次数增加,那么此时的累计segment中的个数就是concurrentHashMap的个数
- 当修改次数比上次+1,重新再统计一次concurrentHashMap的个数。
- 如果尝试的次数超过了阈值,那么通过加锁的方式在进行一次统计
- 然后释放锁
- concurrentHashMap和hashmap在hash上的区别
hashmap的hash: hashcode = key的二进制; index = hashcode & (n-1)
concurrentHashMap的hash: 先定位到segment的index位置,再定位到segment中的位置 - 性能
HashTable 和 Collections.syschronizedMap同样可以解决hashMap的高并发问题,但是他们会进行对每一步操作加锁,会造成堵塞。而concurrentHashMap通过引入segment的概念,可以很大程度的解决堵塞问题。 - put操作和get操作的流程
get操作:
a. 先通过key定位到segment的位置
b. 在通过key定位到segment中对应的位置
c. 返回对应的value
put操作:
a. 先通过key定位到segment的位置
b. 在通过key定位到segment中对应的位置
c. 获得写入锁
d. 完成写入的过程
e. 释放锁