jdk1.7和1.8HashMap,ConcurrentHashMap的区别,以及对源码的一点总结

一、HashMap的区别:

  1. 在jdk1.8中,当数组长度到达64,链表高度到达8时,会将链表转化成红黑树
  2. 链表结点由头插法改成尾插法,由于在jdk1.8中每次都要遍历结点,去判断链表的高度
  3. hash算法简化
  4. resize方法的逻辑修改(jdk1.7会出现死循环,jdk1.8不会)
    二、ConcurrentHashMap的区别:

三: jdk1.7HashMap:
put() : 若key为null,则直接在数组下标为0的链表,若key不为null,先对keyhash,再对Hash进行与(table.length-1)进行与操作,得到数组下标,若table[i]为空,则table[i]=entry,不为空,则先遍历,已存在该key,覆盖,若不存在,则采用头插法,并使table[i]=该entry;
resize(): 当size大于阈值将扩容,在此时若有并发操作,会出现死循环。若正常扩容,则可以将原来的数据更加散列的放到新的扩容后的数组上。假设元素所在数组下标为i的链表上,原数组长度为length,则元素移动到新数组的下表为i或i+length。
get(): 若key不为null,则先对keyhash,在进行与操作,得到数组下标,遍历链表获取key所对应的value
四:jdk1.7ConcurrentHashMap:
put()方法中的scanAndLockForPut()方法:主要是为了获取锁资源,循环直至获取锁资源,其中retries变量初始为-1,若一直未获取锁资源,首先会进行链表的遍历,若链表遍历到结尾未发现已存在的key,则新建一个HashEntry,修改retries变量的值为0,进入另一个分支,若链表中找到了与当前插入的key相等,则也修改retries变量的值为0,也进入另一个分支,在另一个分支中,每次循环都会让retries变量自增,当达到某一值后,就会执行lock()方法,等待锁资源,不在循环,当retries变量为偶数时,会判断当前头结点是否与自己刚遍历时的头结点的key相同,若不相同,则表示有其它线程进行了put操作,则将retries修改为-1,重新进行第一分支的操作。
五: jdk1.8HashMap

  1. hash算法简化
  2. resize逻辑改变(不再会出现死锁问题)
  3. 当数组长度达到64,链表高度达到8是,链表转红黑树
  4. 由jdk1.7头插法改成尾插法
    六: jdk1.8ConcurrentHashMap
  5. 取消了segment字段,直接由table数组保存数据
  6. 由数组+单向链表变更为table数组+单向链表+红黑树。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值