问题1:HashM安排的初始长度,为何?html
初始长度是 16,每次扩展或者是手动初始化,长度必须是 2的幂。java
由于: index = HashCode(Key) & (length - 1), 若是 length是 2的 幂的话,则 length - 1就是 全是 1的二进制数,好比 16 - 1 = 1111,这样至关因而 坐落在长度为 length的hashMap上的位置只和 HashCode的后四位有关,这只要给出的HashCode算法自己分布均匀,算出的index就是分布均匀的。算法
由于HashMap的key是int类型,因此最大值是2^31次方,可是查看源码,当到达 2^30次方,即 并发
MAXIMUM_CAPACITY,以后,便再也不进行扩容。
问题2:高并发状况下,为何HashMap出现死锁?高并发
咱们看到默认HashMap的初始长度是16,比较小,每一次push的时候,都会检查当前容量是否超过 预约的 threshold,若是超过,扩大HashMap容量一倍,整个表里的全部元素都须要按照新的hash算法被算一遍,这个代价较大。提到死锁,对于 HashMap来讲,貌似只能和链表操做有关。性能
正常ReHash过程,能够看到,每一个元素从新算hash值,将链表翻转(目的遍历每一个bucket上的链表仍是用的是头插法,时间复杂度最低),放到对应的bucket上的链表中优化
问题3:java8对hashMap作了什么优化?code
简单说: java7中 hashMap每一个桶中放置的是链表,这样当hash碰撞严重时,会致使个别位置链表长度过长,从而影响性能。htm
java8中,HashMap 每一个桶中当链表长度超过8以后,会将链表转换成红黑树,从而提高增删改查的速度。源码
参考来源:http://www.mamicode.com/info-detail-2120749.html