currenthashmap扩容原理_HashMap 深入解析(二)
共两篇,本文是第二篇,包含后六节。ps:你看到的是我写的第二遍!~ 坑 die 的有道云,写完之后居然给我清空了,无力吐槽
目录
引言
基本存储结构
Put 方法原理
Get 方法原理
装填因子默认值及作用
HashMap 默认长度及原因
HashMap 的线程安全问题
Java8 中 HashMap 的优化
HashMap 和 HashSet 的关系
线程安全的 HashMap:CurrentHashMap 简介
装填因子默认值及作用
/**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
装填因子默认是 0.75,当 put 值时
// The next size value at which to resize (capacity * load factor).
threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
// 如果大于下一个重置大小的值 则把数组扩大一倍
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length);
hash = (null != key) ? hash(key) : 0;
bucketIndex = indexFor(hash, table.length);
}
意思是说,当数组中的元素的个数 >=总长度*装填因子时,数组长度扩容一倍
HashMap 默认长度及原因
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
hashmap 的默认长度是 16,而且长度必须是 2 的倍数
private void inflateTable(int toSize) {
// Find a power of 2 >= toSize
int capacity = roundUpToPowerOf2(toSize);
threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
table = new Entry[capacity];
initHashSeedAsNeeded(capacity);
}
// 把不是2的倍数的数转换成 > 原始值的2的倍数
private static int roundUpToPowerOf2(int number) {
// assert number >= 0 : "number must be non-negative";
return number >= MAXIMUM_CAPACITY
? MAXIMUM_CAPACITY
: (number > 1) ? Integer.highestOneBit((number - 1) << 1) : 1;
}
之所以必须是 2 的倍数,是因为 HashMap 进行 Entry 数组定位的时候,不是使用的取模操作,而是进行的位操作默认取 hash 值的后四位。
例如:hash 值为 12345 Entry 数组长度是 16 该 hash 在数组中的位置计算不是 12345 mod 16 = 9 而是 12345 & 15 = 9,虽然结果是一样的,但是计算效率会更高,速度更快。
HashMap 的线程安全问题
HashMap 在并发编程中可能导致程序死循环
在多线程环境下,使用 HashMap 进行 put 操作时,如果多个线程同时进行扩容操作,有可能会使链表形成闭环,造成获取 Entry 时死循环,导致 CPU 利用率接近 100%。主要是因为 HashMap 在插入 Entry 的时候是插在链表头的而不是链表尾,具体原因参考:https://www.cnblogs.com/andy-zhou/p/5402984.html
Java8 中 HashMap 的优化
JDK1.8 中 HashMap 是数组 + 链表 + 红黑树实现的,链表长度是大于 8 的话把链表转换为红黑树
JDK1.8 种优化了扩容机制
JDK1.8 中优化了高位运算的算法
等等 虽然有点贱,但是的确还有很多 ~
HashMap 和 HashSet 的关系
// 构造方法中就是初始化一个默认的HashMap
public HashSet() {
map = new HashMap<>();
}
private static final Object PRESENT = new Object();
// 增加元素 就是在HashMap中增加一个Key为增加的元素,值为Object实例的键值对
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
// 判断是否存在也是判断元素是否在HashMap中是否存在
public boolean contains(Object o) {
return map.containsKey(o);
}
综上,HashSet 是通过 HashMap 的 Key 实现的
线程安全的 HashMap:CurrentHashMap 简介
HashMap 存在线程安全问题,HashTable 虽然是线程安全的,但是效率太低。所以在多线程的环境下我们一般使用 CurrentHashMap。
CurrentHashMap 使用了锁分段技术,首先把数据分成一段一段地存储,然后给每一段都加上一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。
有机会的话我会写一篇文章仔细分析,埋个坑,敬请期待 :)
currenthashmap扩容原理_HashMap 深入解析(二)相关推荐
- currenthashmap扩容原理_高并发编程系列:深入探讨ConcurrentHashMap的实现原理(JDK1.7和JDK1.8)...
HashMap.CurrentHashMap 的实现原理基本都是BAT面试必考内容,阿里P8架构师谈:深入探讨HashMap的底层结构.原理.扩容机制深入谈过hashmap的实现原理以及在JDK 1. ...
- currenthashmap扩容原理_ConcurrentHashMap之扩容实现(基于JDK1.8)
1. 概述 ConcurrentHashMap是JDK提供的一种线程安全的HashMap实现,JDK1.8对ConcurrentHashMap进行了大量优化,除了增加了函数式编程特性,还对加锁方式进行 ...
- currenthashmap扩容原理_ConcurrentHashMap实现原理和源码解读
前言 HashMap是java编程中最常用的数据结构之一,由于HashMap非线程安全,因此不适用于并发访问的场景.JDK1.5之前,通常使用HashTable作为HashMap的线程安全版本,Has ...
- Tensorflow2.0---SSD网络原理及代码解析(二)-锚点框的生成
Tensorflow2.0-SSD网络原理及代码解析(二)-锚点框的生成 分析完SSD网络的原理之后,一起来看看代码吧~ 代码转载于:https://github.com/bubbliiiing/ss ...
- halfstone 原理_HashMap的结构以及核心源码分析
摘要 对于Java开发人员来说,能够熟练地掌握java的集合类是必须的,本节想要跟大家共同学习一下JDK1.8中HashMap的底层实现与源码分析.HashMap是开发中使用频率最高的用于映射(键值对 ...
- ORB-SLAM / ORB-SLAM2原理解读+代码解析(汇总了资料,方便大家学习)
注释:本文非原创,初学搜集了很多资料附上链接,方便初学者学习,避免盲目搜索浪费时间. 目录 官方代码链接 代码框架思维导图 参考解读 参考链接- -一步步带你看懂orbslam2源码 ORB-SLAM ...
- Dubbo原理和源码解析之服务引用
github新增仓库 "dubbo-read"(点此查看),集合所有<Dubbo原理和源码解析>系列文章,后续将继续补充该系列,同时将针对Dubbo所做的功能扩展也进行 ...
- Git内部原理之深入解析Git的引用和包文件
一.Git 分支本质 如果对仓库中从一个提交(比如 1a410e)开始往前的历史感兴趣,那么可以运行 git log 1a410e 这样的命令来显示历史,不过需要记得 1a410e 是查看历史的起点提 ...
- 音视频开发(7)---流媒体服务器原理和架构解析
流媒体服务器原理和架构解析 多媒体数据文件 一个完整的多媒体文件是由音频和视频两部分组成的,H264.Xvid等就是视频编码格式,MP3.AAC等就是音频编码格式,字幕文件只是附加文件.目前大部分的播 ...
最新文章
- vue写一个通用的toast弹窗 toast 弹窗 提示
- 年近 40,我在互联网大厂做高龄“大头兵”
- php依次替换文本字符串中的图片src地址
- BOOST使用 proto 转换进行任意类型操作的简单示例
- 计算机组成原理第04章在线测试,计算机组成原理第四章单元测试(二)(含答案).docx...
- 华为与美国公司就授权5G平台展开初期谈判;Linux 中存在严重漏洞;Microsoft 发布 Cosmos DB GA 版……...
- 数据结构之线性表:单链表
- HDU 3487 Play with Chain(Splay)
- c++第三次上机实验项目四
- centos搭建NFS服务器
- Silverlight动态创建XAML对象和遍历对象
- Java 开源 CMS :magnolia
- DH参数法 例题 机器人学
- 计算机视觉知识体系图,计算机视觉系统框架的新构思
- MATLAB | MATLAB配色不够用 全网最全的colormap补充包来啦
- 软件开发学习的5大技巧,你知道吗?
- centOS最全下载地址
- 多任务多目标 CTR 预估技术
- 张量学习(6):张量代数
- Navicat中设计表时int类型的长度说明