Java集合

HashMap原理:

底层结构: 数组+链表+红黑树

put()方法:

  • key值经过hash函数计算与数组长度减一做&运算,定位数组位置,如果当前hash桶有值,则equals比较,不同则存入链表,如果链表长度大于8且数据总量大于64,则转为红黑树,当数组占用达到长度乘以阈值时进行2倍扩容

get()方法:

  • 计算key值hash与数组长度减一取模,定位数组位置,之后通过equals方法挨个比较链表或红黑树的节点,相同则返回对应value

为什么底层使用红黑树结构?

  • 红黑树是一种类平衡二叉树,查找元素时使用二分查找,logn的复杂度,而链表是n的复杂度,数据越多,性能优势越明显

为什么不直接使用数组+红黑树?

  • 数据少的时候,hash冲突少,树的查找优势不明显,同时每次插入,更新都要旋转树,也是一种性能开销

为什么HashMap底层结构用红黑树而不是AVL树?

  • 二叉树在一些极端情况下容易发生数据倾斜,无法保证性能;AVL平衡二叉树,每次插入更新都要旋转树结构,开销很大;红黑树不追求完全平衡,可以在保证大致平衡的基础上减少旋转的开销,最多三次旋转,而查询最多也只是多比较一次而已

ConcurrentHashMap

1.7版本前
结构:Segment数组 + HashEntry数组
原理:Segment是ConcurrentHashMap的一个内部类,他继承了ReentrantLock,所以是一个可重入锁,segment默认为16,每个segment上一把锁,所以支持最大并发数是16

每个segment下有多个HashhEntry,锁的粒度还是不够细

jdk1.8版本
结构:数组 + 链表 + 红黑树
原理:抛弃了原有的分段锁,采用了CAS+synchronized实现了更加细粒度的锁,每个node上一把锁,node为链表头结点或红黑树的根节点,锁的粒度比较细,可以很好的支持并发编程,

问题:
为什么1.8版本要使用内置锁synchronized代替reetrantLock可重入锁?
1.6版本,synchronized进行了重大升级,从无锁到偏向锁到轻量锁到重量级锁

ConcurrentHashMap的get方法要不要加锁?
get不需要加锁,因为Node的元素value和指针Next是用volatile修饰的,所以A修改节点的value或者新增节点的时候对B线程来说是可见的

get方法不需要加锁与volatile修饰的hash桶数组有关吗?
没关系,hash桶数组table是用volatile修饰主要是保证在数组扩容的时候保证可见性

ConcurrentHashMap为什么不支持key或value为null?
因为如果允许value为null,那么调用get方法的时候返回一个null,你不知道是value为null,还是没找到key

ConcurrentHashMap的并发度是多少?
由于是以每个hash桶的数组元素做为锁的粒度,所以它的并发度就是数组长度

ConcurrentHashMap的迭代器是强一致性还是弱一致性?
不同于HashMap,它是弱一致性,迭代器创建后会按照hash表结构遍历每一个元素,遍历过程中元素是可以变化的,如果是遍历过的那就体现不出来,没有遍历过的就可以体现出来,这就是弱一致性。

ConcurrentHashMap和HashTable哪个效率更高?
ConcurrentHashMap效率更高,HashTable是把整个hash表加锁,而ConcurrentHashMap是以每个数组元素为单位通过CAS和synchronized进行加锁,锁的粒度更小。

HashTable锁的机制是怎样的?
HashTable是使用synchronized来实现线程安全的,给整个hash表加了一把大锁,多线程访问,只有一个线程能获取锁,这个性能就差很多

多线程下还有其他安全的操作map的方法吗?
有Collections.synchronizedMap方法,但是它的本质也是对hashmap进行了封装,也是全表锁,多线程环境下性能很差

参考博客链接:
https://blog.csdn.net/yunzhaji3762/article/details/113623168

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值