Hashmap、ConcurrentHashmap部分面试总结相关

文章介绍了HashMap和ConcurrentHashMap的底层实现,包括Java7和Java8的区别。HashMap是非线程安全的,基于数组和链表/红黑树实现,可能出现hash冲突和线程安全问题。而ConcurrentHashMap是线程安全的,早期版本使用分段锁,新版本则采用CAS和Synchronized确保并发安全。
摘要由CSDN通过智能技术生成

说明:以下是自己对hashmap和ConcurrentHashmap两个map面试知识点的总结,可能并不是那么全面深入,只是罗列面试常问的。

一、HashMap

HashMap的底层主要是基于数组和链表来实现的,它之所以有相当快的查询速度主要是因为它是通过计算散列码来决定存储的位置。HashMap中主要是通过key的hashCode来计算hash值的,只要hashCode相同,计算出来的hash值就一样。如果存储的对象对多了,就有可能不同的对象所算出来的hash值是相同的,这就出现了所谓的hash冲突。解决hash冲突的方法有很多,HashMap底层是通过链表来解决hash冲突的。也就是说,其链表结果主要是用来解决hash冲突的。

1、java1.7 hashmap结构

由数组加链表组成,数组中每个元素存储的是一个链表的头结点,也就是hashmap内部定义的entity,每个entity包含三个元素:key、value和指向下一个entity的next。

2、java1.8 hashmap结构

由数组+链表+红黑树组成,使用一个Node数组来存储数据,但这个Node可能是链表结构,也可能是红黑树结构,如果插入的key的hashcode相同,那么这些key也会被定位到Node数组的同一个格子里。如果同一个格子里的key不超过8个,使用链表结构存储。如果超过了8个,那么会调用treeifyBin函数,将链表转换为红黑树。

3、hashmap为什么线程不安全

因为hashmap在做插入操作时会调用一个addEntry的方法,如果多个线程同时调用这个方法,那么会同时得到现在的数组位置存放的链表的头结点,然后一个线程写入新的头结点之后,其他线程也会写入新的头结点,这样就会造成一个数据覆盖丢失的问题。

4、hashmap死循环

HashMap的死循环问题发生在JDK1.7版本中,此版本hashmap采用的是头插法,在链表、多线程环境以及自己扩容机制影响下会发生死循环

在Java1.8之后改用尾插法,解决了链表死循环的问题。

二、ConcurrentHasnMap

ConcurrentHasnMap线程安全,所以可以在多线程环境下替换HasnMap,主要是利用了自身的分段锁技术,首先将数据分成一段一段地存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。

1、Java1.7 ConcurrentHashmap结构

ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成。Segment是一种可重入锁(ReentrantLock),在ConcurrentHashMap里扮演锁的角色;HashEntry则用于存储键值对数据。一个ConcurrentHashMap里包含一个Segment数组。Segment的结构和HashMap类似,是一种数组和链表结构。一个Segment里包含一个HashEntry数组,每个HashEntry是一个链表结构的元素,每个Segment守护着一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得与它对应的Segment锁。

2、Java1.8 ConcurrentHashmap结构

ConcurrentHashMap 1.8 抛弃了Segment分段锁机制,采用Node + CAS + Synchronized来保证并发安全进行实现,并且Node的val和next都用volatile保证,保证了可见性,采用table数组+链表+红黑树的存储结构。以table数组元素作为锁,利用CAS+Synchronized来保证并发更新的安全,从而实现了对每个数组元素(Node)进行加锁,进一步减少并发冲突的概率。

3、为什么在有Synchronized的情况下还要使用CAS?

因为CAS乐观锁的特性,在并发不是很激烈的情况下它比Synchronized和ReentrentLock的效率要高,如果CAS保障不了线程安全的情况下再转成Synchronized 来保证线程安全,这样大大提高了低并发下的性能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值