hashtable,hashMap,concurrentHashMap

Posted hup666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hashtable,hashMap,concurrentHashMap相关的知识,希望对你有一定的参考价值。

一  功能简介

Hashtable

实现方式: 底层数组+链表
初始大小:11
扩容:newSize = oldSize*2+1; 超过3/4 即0.75时扩容
存放键值对要求: key 和 value 都不能为null
线程安全性:线程安全,实现方式是在修改数据时锁住整个HashTable,效率低

父类:Dictionnary (已废弃,所以子类也都不推荐使用了) ,Hashtable 属于遗留类

 

HashMap
实现方式:底层 数组+链表
初始大小:16
扩容:newSize = oldSize*2; map中元素总数超过Entry数组的75%,触发扩容操作
存放键值对要求:key 和 value 都允许为null,这种key只能有1个
线程安全性:不安全

父类:AbstractMap

 

ConcurrentHashMap
实现方式:分段的数组 + 链表实现
通过把整个Map分为N(默认16)个部分(槽),相当于是长度为16的槽数组,

每个槽都继承了ReentrantLock,所以每个槽有一把锁,相比HashTable, 效率提升了N倍(读操作不加锁,因类型为volatile 保证能读到最新的值)

扩容:段内扩容

 

二   实现逻辑

2.1  hashMap的内部实现逻辑

  java7  
hashmap 里面是一个数组,数组中每个元素是一个Entry类型的实例
每个Entry的实例包含4个属性,hash,key,value,next

当put进入某个(key,value)时,会对key进行hash再获取到散列地址,相同散列地址的键值对,存放到同一个链表上(默认放链表头)

扩容顺序:先扩容再插入新值

  java8

进行了优化,如果链表中元素超过8个,就转换为红黑树,以减少查询的复杂度 O(logN)
扩容顺序:先插入新值,再扩容

 

2.2  ConcurrentHashMap 的实现逻辑

  java 7 

       ConcurrentHashMap的思路和HashMap思路是差不多,但是因为它支持并发操作,所以要复杂一些,
整个ConcurrentHashMap由16个Segment组成,Segment代表“部分” 或 “一段”的意思,所以很多地方将其描述为分段锁,
ConcurrentHashMap是一个Segment数组, 其中 Segment 通过继承 ReentrantLock 来进行加锁,即每个锁锁住一个Segment,这样保证线程安全
ConcurrentHashMap的扩容,长度初始化后,无法对 Segment数组进行扩容的,默认长度16,扩容是对Segment里面 的数组进行扩容,每个Segment 想当于一个hashMap

 

 java 8

也用到了红黑树,逻辑和上面类似

 

2.3  HashMap中 Entry节点怎么存储?

      散列表table是1个Entry数组,保存Entry实例,
对于冲突:在开散列中,如果若干个entry计算得到相同的散列地址(不同的key也可能计算出相同的散列地址),这些entry 被组织成一个链表,以table[i]为头指针

 

2.4  集合的长度扩容机制:(rehash
当键值对的数量>=设定的阈值(capacity*0.75)时,为保证性能,会进行重散列(重新通过key, length等计算散列地址)

分2步
1  扩容table的长度,2倍
2  转移table中的entry,从旧table转移到新的table (转移过程中,对key进行重新计算散列地址)

 

2.5 如何计算具体数组位置?

 使用 key 的 hash 值对数组长度进行取模就可以了

 

三  结论

      虽然hashtable 是线程安全的,但由于其性能低下(锁整个table) 而且父类已废弃其属于遗留类,所以不推荐使用,

如果是单例模式下,可用hashMap

如果多线程模式下,推荐使用 ConcurrentHashMap 

 

以上是关于hashtable,hashMap,concurrentHashMap的主要内容,如果未能解决你的问题,请参考以下文章

hashmap和hashtable的区别

HashMap于Hashtable的区别

HashTable和HashMap的区别详解

HashMap和HashTable简介和区别

HashTable和HashMap的区别详解

ConcurrentHashMap-----不安全线程hashmap-安全线程-hashtable