Java -- ConcurrentHashMap相关的几个问题

注:前四题都是在JDK1.7的基础上进行解答,部分图是从一些大牛博客上参考的。
参考资料:https://blog.csdn.net/jjc120074203/article/details/78625433
https://www.cnblogs.com/zq-boke/p/8654539.html
《Java并发编程的艺术》 方腾飞 魏鹏 程晓明

  • 1、ConcurrentHashMap底层数据结构是什么?
    答:底层数据结构是:数组+数组+链表
    解释:
    底层结构图解(图1-1):
    在这里插入图片描述
    剖析源码:
    (1)ConcurrentHashMap属性:Segment<K,V> 类型的 segments数组;
    在这里插入图片描述在这里插入图片描述
    (2)Segment类是ConcurrentHashMap的一个内部类,它含有一个HashEntry类型的数组table,所以每一个segment中都含有一个table数组,同时table中的每一个元素都是一个链表。所以底层数据结构是数组+数组+链表(就如底层结构图解所示)。
    在这里插入图片描述
    HashEntry内部类:
    在这里插入图片描述
  • 2、ConcurrentHashMap通过什么保证线程安全?
    答:<1>分段锁机制;
    Segment类继承了ReentrantLock,所以每一个Segment都相当于一个锁,如(图1-1)中,segments整体并没有加锁,每一个segments[x]加锁;
    在这里插入图片描述
    <2>put方法采用Segment内部类中的put方法,所以put方法是线程安全的。
    在这里插入图片描述
    补充:
    ReentrantLock(可重入锁),顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁。除此之外,该锁还支持获取锁时的公平和非公平性选择。
    公平性问题:如果在绝对时间,先对锁进行获取的请求一定先被满足,那么这个锁是公平的。反之,是不公平的。公平的获取锁,也就是等待时间最长的线程最优先获取锁,也可以说锁获取是顺序的。ReentrantLock提供了一个构造函数,能够控制锁是否是公平的。
  • 3、HashTable和concurrentHashMap线程安全保证机制是否一样?
    答:不一样。
    (1) HashTable采用的是全局锁,对整个put()方法进行同步,用synchronized关键字进行修饰;
    在这里插入图片描述
    (2)ConcurrentHashMap采用的是分段锁机制,并没有对整个segments数组进行加锁,而是每一个segments[x]就是一个ReentrantLock,即对每一个segments[x]进行加锁,不属于全局锁。(结合图1-1和第二题可知)
  • 4、HashMap、Hashtable和ConcurrentHashMap区别是什么?
    (1)继承:
    HashMap:
    在这里插入图片描述
    Hashtable:
    在这里插入图片描述
    ConcurrentHashMap:
    在这里插入图片描述
    (2)底层数据结构:
    HashMap:数组+链表
    Hashtable:数组+链表
    ConcurrentHashMap:数组+数组+链表
    (3)属性:
    HashMap: 允许一个键为null,允许多个值为null; 在这里插入图片描述
    Hashtable: 无论键还是值都不允许为null;在这里插入图片描述
    ConcurrentHashMap: 在这里插入图片描述
    (4)线程安全问题:
    HashMap:非线程安全;
    在这里插入图片描述
    Hashtable:线程安全的,put方法被synchronized关键字修饰,锁住整张hash表,使其只被一个线程占用;
    ConcurrentHashMap:线程安全的,采用分段锁机制,ConcurrentHashMap中则是 一次锁住一个桶。ConcurrentHashMap默认将hash表分为16个桶,诸如get,put,remove等常用操作只锁当前需要用到的桶。 这样,原来只能一个线程进入,现在却能同时有16个写线程执行,并发性能的提升是显而易见的。。
    (5)扩容方式:
    HashMap:2倍扩容
    Hashtable:2倍原容量加1 在这里插入图片描述
    ConcurrentHashMap:2倍扩容,但是它只是对table[]数组进行扩容,不能对segments[]数组进行扩容。 在这里插入图片描述
  • 5、ConcurrentHashMapJDK1.7 、1.8的区别有哪些?
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值