Jdk1.8中的循环链

Jdk1.8中的循环链

说到HashMap的循环链,应该就会想到一些关键字:jdk1.7,链表,多线程,扩容,头插法。jdk1.8的时候,新增了红黑树结构,头插法也改成了尾插法,所以,Jdk1.8的hashmap就没有循环链了吗?

jdk1.7

先简单说说1.7的循环链形成吧,核心代码如图

步骤

  1. 一条链表A->B->null;
  2. 线程1准备扩容时,此时链表上的A.next = B,然后被挂起;
  3. 线程2扩容时,把A,B两个对象都rehash了,恰好又在一条链上,由于是头插法,现在B.next=A;
  4. 线程1接着扩容,rehashA对象,放在链表上,接着rehashB对象,放在链表上
  5. 由于线程2的原因,B.next=A,线程一发现B.next不为空,接着reHashA,结果形成循环链A->B->A;
JDK1.8

  1. jdk1.8的链表,增加了一个尾部指针,所以插入的时候,直接插入在链表尾部,避免了循环链

  2. 但是1.8是在链表转换树或者对树进行操作的时候会出现线程安全的问题,两个红黑树节点的父亲节点相互引用才可以导致无法走出这个for语句

  1. balanceInsertion()方法对树进行一个重新的平衡时,也会出现线程安全问题,可能Node节点转换为TreeNode结点异常

总结:

主要原因其实是多线程下操作同一对象时,对象内部属性的不一致性导致的。分析方式跟为什么单例要使用双重锁check类似


posted on 2020-08-16 21:44  灰马非马  阅读(246)  评论(0编辑  收藏  举报

导航