• 深入浅出hashMap与hashTable


    比较一下hashMap与hashTable。

    hashMap与hashTable 同样都是 数组+链表的形式去存储数据

    以HashMap为例 默认数组长度为16,每一个数组地下都挂着一个链表

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

    这个时候比如为1的元素下挂着一个链表

    a
    b
    c
     
     
     

    可以理解为16个数组元素下每一个都挂着不计长度的链表

    当我的数据来得时候,每一个数组元素都可以存放着不同的key值,而且可以存放多个(这个计算的过程我们称之为哈希碰撞)。 链表里存放着不同的key值。

    值得一提的是, 当每次put的元素在1-16元素范围内的比例超过0.75(装载因子)的时候 进行翻倍扩容 ,数组的长度会从16变成32,32变64.

    当数组长度已经变成64并且链表长度达到8以后进行树化

    什么是树化 即 链表变成以红黑树的方式去存储,

    红黑树的好处又是什么,

    红黑树在存储的时候会按照适配的比例去挂载分支数据,也就是说不会出现一个分支一直挂数据 另一个分支无数据的情况,

    这个时候去找数据 就会比链表里找数据要缩短时间。


    hashTable是线程安全的,而hashTable不是。为什么这样说,对源码有兴趣的同学可以打开你的项目找到如下这段代码

     1 public synchronized V get(Object key) {
     2         Entry<?,?> tab[] = table;
     3         int hash = key.hashCode();
     4         int index = (hash & 0x7FFFFFFF) % tab.length;
     5         for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
     6             if ((e.hash == hash) && e.key.equals(key)) {
     7                 return (V)e.value;
     8             }
     9         }
    10         return null;
    11     }
    View Code

    可以看到这个关键字:synchronized 。 这个关键字是用来干嘛的,对没错就是  线程同步

    什么叫线程同步,我的理解是 当我的数据同时访问的时候,a和b 同时用哈希算法算到了同一个位置  那么 b就需要排队。等a存储完成以后 b再去存储。这就是线程安全。那么带来的问题就是 性能会很差。如果高并发的情况下,会让人抓狂。

    其实HashMap使用得当 是非常安全的。 而且很好用。

    提一点 jdk1.5以后 为了解决线程安全+效率问题  

    CorruntHashMap 

    应运而生。

    这个map呢  你可以理解图中的 数据元素和链表都是上了锁的。  那么只有在哈希运算的时候,并且两个来源数据都计算到同一个位置的时候 才会触发,有序排队存储。

    
    
  • 相关阅读:
    什么是知行动手实验室?
    SpringBoot Admin2.0 集成 Java 诊断神器 Arthas 实践
    一文读懂容器存储接口 CSI
    AI 事件驱动场景 Serverless 实践
    一不小心,它成为了 GitHub Alibaba Group 下 Star 最多的开源项目
    5G 和云原生时代的技术下半场,视频化是最大最新的确定性
    基于 RocketMQ Prometheus Exporter 打造定制化 DevOps 平台
    Knative 基于流量的灰度发布和自动弹性实践
    阿里的 RocketMQ 如何让双十一峰值之下 0 故障?
    阿里巴巴开源容器镜像加速技术
  • 原文地址:https://www.cnblogs.com/wuhaojs/p/15342056.html
Copyright © 2020-2023  润新知