HashMap ConcurrentHashMap

问题描述

翻翻别人的面试经历

这里在知乎上看到的,分享出了本身面试阿里Java岗的面试题。html

clipboard.png

看了一下,除了Spring以外的其余不少题都不会,可是不能拿学校没讲Java做为借口,由于可能讲了也不会。面试

可是第九个问题,我以为应该马上话时间研究研究了,由于以前在缓存中用到了这个。数据库

当时也不明白具体HashMapConcurrentHashMap究竟有什么区别。数组

clipboard.png

只是记得以前看过有关大数据的场景下利用缓存减轻数据库压力的文章,文中说经常使用ConcurrentHashMap,因此这里缓存就用这个了,其实并不懂原理,下面,让咱们一块儿来研究一下。缓存

Map

Map你们都熟悉了,Java中也有,JavaScript中也有。安全

Map是一种键值对类型的数据结构,根据键映射到值。数据结构

不分析源码了,就把思想给你们讲一下,如下主要以图为主。多线程

HashMap

Java7

clipboard.png

HashMap的本质是一个可变长度的数组,在数组中每一个位置保存的是一个Entry节点,该节点存储有hashkeyvaluenext等信息。并发

Java7中的HashMap实现与咱们在数据结构中学习的相似,对key进行hash,若是冲突了,则添加到链表中。性能

而后查询的时候就先根据hash找到相应的位置,而后根据链表逐一比较,返回相应的value。时间复杂度取决于链表的长度,时间复杂度为O(N)

Java8

clipboard.png

Java8中对HashMap进行了优化,若是链表中元素超过8个时,就将链表转化为红黑树,以减小查询的复杂度,将时间复杂度下降为O(logN)

HashMap没有对多线程的场景下作任何的处理,不用说别的,就两个线程同时put,而后冲突了,二者须要操做一个链表/红黑树,这确定就会有错误发生,因此HashMap是线程不安全的。

HashTable

HashTableJava7中的HashMap相似,也是一个数组加链表,不过这个线程安全。

HashTable线程安全,可是它的线程安全是依赖将全部修改HashTable的代码块都用synchronized修饰。

synchronized关键字咱们以前在单例模式中用到过,它修饰的代码块,同一时刻只容许一个线程访问,其余线程会被阻塞,等待该线程执行完再执行。

因此,在HashTable中,一个线程在put,其他的线程在get的时候就会被阻塞,没法并行。因此不推荐使用HashTable,虽然它线程安全。

ConcurrentHashMap

HashMap线程不安全,HashTable性能又很差,固然须要设计一个新类去解决这些问题,这就是ConcurrentHashMap

Java7

clipboard.png

这是Java7中实现线程安全的思路,ConcurrentHashMap16segment组成,每一个segment就至关于一个HashMap(数组+链表)。

segment最多16个,想要扩容,就是扩充每一个segment中数组的长度。

而后只要实现每一个segment是线程安全的,就让这个Map线程安全了。每一个segment是加锁的,对修改segment的操做加锁,不影响其余segment的使用,因此理想状况下,最多支持16个线程并发修改segment,这16个线程分别访问不一样的segment

同时,在segment加锁时,全部读线程是不会受到阻塞的。

这样设计,putget的基本操做就是先找segment,再找segment中的数组位置,再查链表。

Java8

后来人们发现Java7这样设计太复杂了,回归本质。

HashMap线程不安全的问题彻底都是出在对链表/红黑树的操做上,为何非要建一个segment加锁呢?直接对链表/红黑树加锁不就行了?

clipboard.png

因此Java8ConcurrentHashMap彻底就是HashMap进行加锁,实现线程安全。

这里总结的很简单,其实源码中对这个的实现特别复杂,有兴趣的能够去看看,反正我是看着头大。

总结

  1. HashMap线程不安全。
  2. HashTable线程安全,但性能差,不推荐使用。
  3. ConcurrentHashMap线程安全。
  4. ConcurrentHashMapJava7中使用segment实现,对每一个segment加锁。
  5. ConcurrentHashMapJava8中是直接在HashMap的基础上进行加锁。

参考文献:

Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析
ConcurrentHashMap、HashTable、HashMap三兄弟

相关文章
相关标签/搜索