hashmap的头插法问题
无意当中了解了这个问题,hashmap的数据插入的时候分为头插法和尾插法,头插法在jdk1.8之前,尾插法在jdk1.8实现。
因为头插法会出现链表成环的问题,所以插入方式进行了改变,变为尾插法。即使链表成环,如果不在这个链表中查询也不会出现问题,即使查询,如果查询的不是环中的值,也不会出现问题,只有查询环中的值才会出现问题。
说明:hash值和插入数据仅作说明问题用,源码请参考其它博主的优秀文章。
例如次数要查询5并不会出现问题,但是查询hash值为2,但是value不再这个链表中的数据会出现问题,例如查询33(hash=2)就会出现死循环的问题。
那么这个链表是如何成环的?
必须是在多线程环境下,在一定的条件下才可能形成环路。
假设有两个线程,线程1和线程2,在插入数据后都要进行扩容操作,线程1先进行扩容操作。
此时线程1要进行 扩容操作,对hash=2的链表取出再放入新的链表的时候(假设链表中hash值依然相同),线程中断,此时只取得了e=5,next= 9;然后线程2执行。
线程2正常执行:
然后线程1继续执行,
此时,再继续执行的时候,原数据已经被线程2更改,所以会从新的、线程2更改后的数据中取值,此时,在hash=2这个桶中,e=9,next=5,继续执行,
执行到现在依然没有什么问题,继续执行,由线程2执行后的表可以,此时e=5,5.next=null ,线程1会进行本链表的最后一次插入操作,会将值插在链表的头部,
此时,在插入数值后,value5是指向value9的,所以会替换之前的value5指向null,这个地方是我看了好多文章之后的个人理解,仅供参考。
最终的表现形式: