面试之Java圣经4

前言

继续聊集合上篇说了Set和List,这次聊Map,Map的知识非常多


一、Map?

map是采用键值对的存储方式,键不可以重复,但值可以。

HashMap和HashTable 的区别

       HashMap 继承了 AbstractMap 类,HashMap基于哈希表的Map接口实现,利用哈希算法根据hashCode()来配置存储地址,它的底层数据结构是采用数组+链表(JDK1.8之前)而JDK1.8及以后采用数组+链表+转红黑树(当链表长度超过阈值(8)时且数组长度大于64时,将链表转换为红黑树)的数据结构.HashMap的初始容量是16,当链表数组的容量超过初始容量的0.75时,再散列将链表数组扩大2倍,把原链表数组的搬移到新的数组中。且HashMap 不是线程安全的,在多线程环境下,操作HashMap会导致各种各样的线程安全问题,比如在HashMap扩容重哈希时出现的死循环问题,脏读问题等。如果多个外部操作同时修改 HashMap 的数据结构比如 add 或者是 delete,必须进行同步操作,仅仅对 key 或者 value 的修改不是改变数据结构的操作。可以选择线程安全的synchronizedMap 或者是 ConcurrentHashMap。

        HashTable 继承了 Dictionary 类,HashTable 不允许空的 key 和 value 值。HashTable 的初始长度是11,之后每次扩充容量变为之前的 2n+1(n为上一次的长度)HashTable 本身就是线程安全的容器。

HashMap为什么要转红黑树?

        jdk1.8之前解决hash冲突的方法是同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。当链表的长度太长是,就转为红黑树,提升查询效率。

快速失败(fail—fast)

        HashMap 遍历使用的是一种快速失败机制,它是 Java 非安全集合中的一种普遍机制,这种机制可以让集合在遍历时,如果有线程对集合进行了修改、删除、增加操作,会触发并发修改异常。

        它的实现机制是在遍历前保存一份 modCount ,在每次获取下一个要遍历的元素时会对比当前的 modCount 和保存的 modCount 是否相等。

        快速失败也可以看作是一种安全机制,这样在多线程操作不安全的集合时,由于快速失败的机制,会抛出异常.

ConcurrentHashMap和HashTable的区别

        ConcurrentHashMap是HashMap的一个线程安全的、支持高效并发的版本,在默认理想状态下,ConcurrentHashMap可以支持16个线程执行并发写操作及任意数量线程的读操作。上文提到在多线程HashMap会出现线程不安全的情况,在并发种往往通常使用ConcurrentHashMap,在JDK1.7中ConcurrentHashMap采用了数组+Segment+分段锁的方式实现。而在JDK1.8种ConcurrentHashMap参考了JDK8 HashMap的实现,采用了数组+链表+红黑树的实现方式来设计,内部大量采用CAS操作。并发控制使⽤synchronized 和 CAS 来操作。在JDK1.8的Nod节点中value和next都用volatile修饰,保证并发的可见性。可以理解为,synchronized 只锁定当前链表或红⿊⼆叉树的⾸节点,这样只要 hash 不冲突,就不会产⽣并发,效率⼜提升 N 倍

Hashtable

        Hashtable的底层数据结构类似都是采⽤数组+链表 的形式,数组是数据的主体,链表则是主要为了解决哈希冲突⽽存在的;Hashtable(同⼀把锁) :使⽤ synchronized 来保证线程安全,效率⾮常低下。当⼀个线程访问同步⽅法时,其他线程也访问同步⽅法,可能会进⼊阻塞或轮询状态,如使⽤ put 添加元素,另⼀个线程不能使⽤ put 添加元素,也不能使⽤get,竞争会越来越激烈效率越低;

        在执行效率上,Hashtable的效率远远低于ConcurrentHashMap,主要原因还是因为Hash Table使用了一种全表加锁的方式。


总结

HashMap总结的可能不全,想到了自己在补一下。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值