HashMap  可以允许key为null,value为null,但HashMap的是线程不安全的  HashMap 底层是数组 + 链表的数据结构

  • 在jdk 1.7 中 map集合中的每一项都是一个 entry  
  • 在jdk 1.8 中 map 集合中的每一项都是一个node

这张图我解释一下 在每个HashMap中 维护了四个属性 分别是 hash ,map ,key ,next

因为底层是数组加链表 数组的默认大小是16 每一个 用户put值的时候都会向这个数组进行添加 这里的添加算法就是 hash算法,一旦用户的数据向这个数组的某一项进行第二次辅助则这时就会使用链表的数据结构 一直向下延申 这个是jdk1.7 的做法

而到了jdk1.8以后 在延申的过程中一旦发现 延申的数量大于8个就会使用另一种的数据结构 红黑树以树的形式进行扩展进行添加

这时肯定会有人问刚刚一直往下延申这时 的横向延申不够怎么办 就是数组的长度不足怎么办 这时数组当然也是会扩容 以原理的二倍进行扩容相对来说效率比较高

HashMap 数组+链表+红黑树 在单线程的情况下简直是完美的

但在多线程的情况下是不完美的 会导致线程不安全

线程不安全 :

多线程操作一系列操作的时候和单线程操作表现的结果不致就说明线程非安全在 hashmap1.7中头插法hsah map是线程不安全的

这时我们的Hashtable 出现了

  • hashtable不接受key 或者 value为空
  • 线程安全

但是 是线程安全的 但在高并发 或者负载均衡的轮询等 效率太 低

ConcurrentHashMap

采用的是分段锁

在并发的概念中 有一个编程思想是CAS方式 采用无锁的方式 保证线程的安全 保证了原子性 效率比 synchronized 高

接下来我们对比一下HashMap 和 ConcurrentHashMap的put 方式

Hashmap 的put方法

ConcurrentHashMap的put 方法

点入到ConcurrentHashMap的put 方法

这时我们在ConcurrentHashMap集合中看到 好多volatile关键字

volatile

这个关键字 保证每次读到的都是主内存里面最新的值

  • 扩容:段内扩容(段内元素超过该段对应Entry数组长度的75%触发扩容,不会对整个Map进行扩容),插入前检测需不需要扩容,有效避免无效扩容
  • ConcurrentHashMap默认将hash表分为16个桶,诸如get、put、remove等常用操作只锁住当前需要用到的桶。这样,原来只能一个线程进入,现在却能同时有16个写线程执行,并发性能的提升是显而易见的。

HashMap和ConcurrentHashMap和HashTable的底层原理与剖析的更多相关文章

  1. 沉淀再出发:java中的HashMap、ConcurrentHashMap和Hashtable的认识

    沉淀再出发:java中的HashMap.ConcurrentHashMap和Hashtable的认识 一.前言 很多知识在学习或者使用了之后总是会忘记的,但是如果把这些只是背后的原理理解了,并且记忆下 ...

  2. HashMap与ConcurrentHashMap、HashTable

    (1)HashMap的线程不安全原因一:死循环 原因在于HashMap在多线程情况下,执行resize()进行扩容时容易造成死循环. 扩容思路为它要创建一个大小为原来两倍的数组,保证新的容量仍为2的N ...

  3. hashmap,ConcurrentHashMap与hashtable的区别

    1.hashmap与hashtable的区别 1.我们从他们的定义就可以看出他们的不同,HashTable基于Dictionary类,而HashMap是基于AbstractMap.Dictionary ...

  4. HashMap、ConcurrentHashMap以及HashTable(面试向)

    ---->HashMap 在java1.7中,hashmap的数据结构是基于数组+链表的结构,即我们比较熟悉的Entry数组,其包含的(key-value)键值对的形式.在多线程环境下,Hash ...

  5. hashMap、ConcurrentHashMap、hashTable、TreeMap、LinkedHashMap用法区别详解

    Java集合中设计了一个接口Java.util.Map,它实现类中hashMap.hashTable.TreeMap.ConcurrentHashMap.LinkedHashMap. Map类型的集合 ...

  6. 集合总结五(Hashtable的实现原理)

    一.概述 上一篇介绍了Java8的HashMap,接下来准备介绍一下Hashtable. Hashtable可以说已经具有一定的历史了,现在也很少使用到Hashtable了,更多的是使用HashMap ...

  7. Hashtable,HashMap和ConcurrentHashMap的原理及区别

    一.原理 Hashtable 底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashM ...

  8. HashMap,Hashtable,ConcurrentHashMap 和 synchronized Map 的原理和区别

    HashMap 是否是线程安全的,如何在线程安全的前提下使用 HashMap,其实也就是HashMap,Hashtable,ConcurrentHashMap 和 synchronized Map 的 ...

  9. HashMap,ConcurrentHashMap原理。Collection(list,set,map集合区别)。和CAS

    collection里面有什么子类?(list和set是实现了collection接口的.) List: 1.可以允许重复的对象(可重复,有序集合).2.可以插入多个null元素.3.常用的实现类有 ...

随机推荐

  1. @Override must override a superclass method 有关问题解决

    1.Java开发环境时 如果在使用Eclipse开发Java项目时,在使用 @Override 出现以下错误: The method *** of type *** must override a s ...

  2. 170209、mysql索引的建立

    用到索引最普通的情况,是为出现在where子句的字段建一个索引.为方便讲述,我们先建立一个如下的表. Code代码如下: CREATE TABLE mytable ( id serial primar ...

  3. docker运行oracle11g

    image docker pull registry.cn-hangzhou.aliyuncs.com/qida/oracle-xe-11g 或者自己自动添加表 create role test_ro ...

  4. Oracle的服务介绍以及正常运行必须启动的服务

    成功安装Oracle 11g数据库后,你会发现自己电脑运行速度会变慢,配置较低的电脑甚至出现非常卡的状况,通过禁止非必须开启的Oracle服务可以提升电脑的运行速度.那么,具体该怎么做呢? 按照win ...

  5. 错误0x80070522:客户端没有所需的特权

    win10或win7 C盘复制文件等遇到"错误0x80070522:客户端没有所需的特权" 在运行中输入 icacls c:\ /setintegritylevel M

  6. Leetcode 之 Keys Keyboard

    1. 2 Keys Keyboard 先把dp的最小不走都设置为无穷大(Integer.MAX_VALUE),初始化条件:dp[0] = dp[1] = 0,状态转移方程为dp[i] = Math.m ...

  7. 009-shiro与spring web项目整合【三】验证码、记住我

    一.验证码 1.自定义FormAuthenticationFilter 需要在验证账号和名称之前校验验证码 /** * * <p>Title: CustomFormAuthenticati ...

  8. 让你的代码量减少3倍!使用kotlin开发Android

    (一) 创建Kotlin工程 (二) –秘笈!扩展函数 (三) 缩短五倍的Java Bean 本项目使用的代码地址

  9. sublime txet 3 python 开发环境安装配置

    下载python 下载地址:https://www.python.org/downloads/windows/ 下载sublime text 3 下载地址:https://www.sublimetex ...

  10. go——通道

    相比Erlang,go并未实现严格的并发安全.允许全局变量.指针.引用类型这些非安全内存共享操作,就需要开发人员自行维护数据一致和完整性.Go鼓励使用CSP通道,以通信来代替内存共享,实现并发安全.作 ...