1.put方法!
1.key经过哈希算法得到一个下标
如果改位置没有元素
将key和value封装为一个 1.8node或者是1.7entiy
如果该位置有元素
1.7判断是否需要扩容
需要扩容就扩容
不需要扩容就头插法插入链表
1.8判断改位置的元素是链表node还是红黑树node
链表node,将key和value封装为node,然后尾插法插入链表,尾插法需要遍历链表,如果key存在,直接更新value 插入后如果链表长度大于等于阈值,就链表转化为红黑树
判断是否需要扩容
红黑树node,将key value插入红黑树,如果key存在就更新value,
判断是否需要扩容
2.扩容机制
hashmap的扩容机制,两种情况。
1.有数据的节点数量达到负载因子后,就发生扩容。
2.数组长度<64,链表长度达到8的时候,发生扩容
树化:当数组长度达到64时,链表长度达到8,就链表转化为红黑树。长度<8时,又会转化成链表
3.为什么Hashmap线程不安全
-
1.7的时候,hashmap使用头插法,并发扩容情况下会造成死链
如何扩容? 线程 为什么造成死链? 多线程同时扩容,由于1.7是头插法,扩容后,链表顺序会发生反转, 当一个线程完成了扩容(A->B->C->null)->(C->B->A->null), 另一个线程如果在第一个线程扩容前准备扩容但时间片用完了,在第一 个线程扩容后再次获得时间片,线程2此时的指向为T2->A,T2.next->B(A->B) 此时就发生了死链()。 -
多线程同时执行 put 操作时,如果计算出来的索引位置是相同的,那会造成前一个 key 被后一个 key 覆盖,从而导致元素的丢失。