Java HashMap和ConcurrentHashMap知识点梳理
jdk 8 HashMap 扩容之后旧元素存放位置是?
java 在扩容的时候会创建一个新的 Node<K,V>[],用于存放扩容之后的值,并将旧的Node数组(其大小记作n)置空;至于旧值移动到新的节点的时候存放于哪个节点是根据 (e.hash & oldCap) == 0 来判断的:
① 等于0时,则将其索引位置h不变;
② 不等于0时,则将该节点在新数组的索引位置等于原索引位置加上旧数组长度。Java 中的另一个线程安全的、与 HashMap 极其类似的类是什么?同样是线程安全,它与 Hashtable 在线程同步上有什么不同?
ConcurrentHashMap 类(是 Java并发包 java.util.concurrent 中提供的一个线程安全且高效的 HashMap 实现)。Hashtable 是使用 synchronized 关键字加锁的原理(就是对对象加锁);而针对 ConcurrentHashMap,在 JDK 7 中采用分段锁的方式,而JDK 8 中直接采用了CAS(无锁算法)+ synchronized。HashMap & ConcurrentHashMap 的区别?
除了加锁,原理上无太大区别。另外,HashMap 的键值对允许有null,但是ConCurrentHashMap 都不允许。为什么 ConcurrentHashMap 比 Hashtable 效率要高?
Hashtable 使用一把锁(锁住整个链表结构)处理并发问题,多个线程竞争一把锁容易导致阻塞;而ConcurrentHashMap降低了锁粒度。ConcurrentHashMap在JDK 7 中使用分段锁(ReentrantLock + Segment + HashEntry),相当于把一个 HashMap 分成多个段,每段分配一把锁,这样支持多线程访问。锁粒度:基于 Segment,包含多个 HashEntry。在JDK 8 中,使用 CAS + synchronized + Node + 红黑树,锁粒度为Node(首结点)(实现 Map.Entry)。ConcurrentHashMap 在 JDK 8 中,为什么要使用内置锁 synchronized 来代替重入锁 ReentrantLock?
①、粒度降低了;
②、JVM 开发团队没有放弃 synchronized,而且基于 JVM 的 synchronized 优化空间更大,更加自然。
③、在大量的数据操作下,对于 JVM 的内存压力,基于 API 的 ReentrantLock 会开销更多的内存。ConcurrentHashMap 的并发度是什么?
程序运行时能够同时更新 ConccurentHashMap 且不产生锁竞争的最大线程数。默认为 16,且可以在构造函数中设置。
当用户设置并发度时,ConcurrentHashMap 会使用大于等于该值的最小2幂指数作为实际并发度(假如用户设置并发度为17,实际并发度则为32)ConcurrentHashMap 加锁机制
它加锁的场景分为两种:
1、没有发生hash冲突的时候,添加元素的位置在数组中是空的,使用CAS的方式来加入元素,这里加锁的粒度是数组中的元素。
2、如果出现了hash冲突,添加的元素的位置在数组中已经有了值,那么又存在三种情况。
(1)key相同,则用新的元素覆盖旧的元素。
(2)如果数组中的元素是链表的形式,那么将新的元素挂载在链表尾部。
(3)如果数组中的元素是红黑树的形式,那么将新的元素加入到红黑树。
第二种场景使用的是synchronized加锁,锁住的对象就是链表头节点(红黑树的根节点)
,加锁的粒度和第一种情况相同。
结论:ConcurrentHashMap分段加锁机制其实锁住的就是数组中的元素,当操作数组中不同的元素时,是不会产生竞争的。ConcurrentHashMap存储对象时(put() 方法):
1> 如果没有初始化,就调用 initTable() 方法来进行初始化;
2> 如果没有哈希冲突就直接 CAS 无锁插入;
3> 如果需要扩容,就先进行扩容;
4> 如果存在哈希冲突,就加锁来保证线程安全,两种情况:一种是链表形式就直接遍历到尾端插入,一种是红黑树就按照红黑树结构插入;
5> 如果该链表长度大于阀值 8(且数组中元素数量大于64),就要先转换成红黑树的结构。下⾯这个⽅法保证了 HashMap 总是使⽤ 2 的幂作为哈希表的⼤⼩。
/**
* Returns a power of two size for the given target capacity.
*/
static final int tableSizeFor(int cap) {
int n = -1 >>> Integer.numberOfLeadingZeros(cap - 1);
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}HashMap红黑树退化为链表的阈值为什么是6?
为了避免频繁地进行链表和红黑树的转化。ConcurrentHashMap get操作需要加锁吗?线程安全吗?
get 方法不需要加锁。因为 Node 的元素 value 和指针 next 是用 volatile 修饰的,在多线程环境下线程A修改节点的 value 或者新增节点的时候是对线程B可见的。这也是它比其它并发集合比如 Hashtable、用 Collections.synchronizedMap()包装的 HashMap 效率高的原因之一。
Java HashMap和ConcurrentHashMap知识点梳理的更多相关文章
- 轻松理解 Java HashMap 和 ConcurrentHashMap
前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常用于在内存中存放数据. 本篇主要想讨论 ConcurrentHashMap 这样一个并发容器,在正式开始之前我觉得有必要谈谈 ...
- JAVA HashMap与ConcurrentHashMap
HashMap Fast-Fail(遍历时写入操作异常) 在使用迭代器的过程中如果HashMap被修改,那么ConcurrentModificationException将被抛出,也即Fast-fai ...
- HashMap 、ConcurrentHashMap知识点全解析
散列表 在了解hashmap之前,要先知道什么是散列表,因为hashmap就是在散列表结构基础上改造而成的.散列表,也叫哈希表,是根据关键码值(key value)而直接进行访问的数据结构.也就是说, ...
- Java7与Java8中的HashMap和ConcurrentHashMap知识点总结
JAVA7 Java7的ConcurrentHashMap里有多把锁,每一把锁用于其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率呢.这 ...
- [Java集合] 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.
注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享. 原文地址: http://blog.csdn.net/zhanger ...
- Java并发相关知识点梳理和研究
1. 知识点思维导图 (图比较大,可以右键在新窗口打开) 2. 经典的wait()/notify()/notifyAll()实现生产者/消费者编程范式深入分析 & synchronized 注 ...
- java基础知识再学习--HashMap与ConcurrentHashMap的区别
引用:http://blog.csdn.net/xuefeng0707/article/details/40834595 从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是 ...
- Java中关于Map的使用(HashMap、ConcurrentHashMap)
在日常开发中Map可能是Java集合框架中最常用的一个类了,当我们常规使用HashMap时可能会经常看到以下这种代码: Map<Integer, String> hashMap = new ...
- 沉淀再出发:java中的HashMap、ConcurrentHashMap和Hashtable的认识
沉淀再出发:java中的HashMap.ConcurrentHashMap和Hashtable的认识 一.前言 很多知识在学习或者使用了之后总是会忘记的,但是如果把这些只是背后的原理理解了,并且记忆下 ...
- Java并发指南13:Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析
Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析 转自https://www.javadoop.com/post/hashmap#toc7 部分内容转自 http: ...
随机推荐
- hgame2025-Crypto小记
hgame2025-Crypto小记 发现积压在文件夹有一段时间了.整理一下发出来. suprimeRSA task.py from Crypto.Util.number import * impor ...
- NumPy学习10
今天学习了3节: 18, NumPy副本和视图 19, NumPy字节交换 20, NumPy Matrix矩阵库 numpy_test10.py : import numpy as np ''' 1 ...
- Hive SQL实现近N周的数据统计查询
文/朱季谦 先前遇到过一个需求,需要基于HIVE统计近N周范围的数据,例如,统计近7周范围的数据指标. 需要用HIVE SQL去实现该功能,而HIVE SQL并没有PostgreSQL那样例如通过函数 ...
- Semaphore.acquire()方法的底层原理
一.acquire() 的工作流程 当调用 acquire() 方法时,实际调用的是 AQS 的 acquireSharedInterruptibly(1) 方法.以下是其详细工作流程: // acq ...
- 🎀FreeMarker 禁止自动转义标签-noautoesc
简介 FreeMarker 是一个用 Java 语言编写的模板引擎,它被设计用来生成文本输出(HTML 网页.电子邮件.配置文件等).在 FreeMarker 中,默认情况下,当你在模板中输出变量时, ...
- FastAPI与SQLAlchemy同步数据库集成
title: FastAPI与SQLAlchemy同步数据库集成 date: 2025/04/15 01:27:37 updated: 2025/04/15 01:27:37 author: cmdr ...
- MySQL 中 `LIMIT 100000000, 10` 和 `LIMIT 10` 的执行速度是否相同?
在MySQL中,LIMIT 100000000, 10和LIMIT 10的执行速度通常不会相同.它们的差异在于如何处理数据的检索. LIMIT 10: LIMIT 10表示从查询结果中获取前10条记录 ...
- css给dom插入/追加文字/内容
A.使用选择器来插入内容 h2:before{ content:"前缀"; } h2:after{ content:"后缀"; } B.指定个别的元素不进行插入 ...
- 让IE6、IE7、IE8支持CSS3的圆角、阴影样式-最好的插件
想做个页面用到css3的圆角和阴影效果,但ie浏览器不支持,之前也听说有插件可以实现,周六在网上找到了一个方法,原文如下: 但凡是前端工程师,都知道IE6,IE7,IE8不支持.或者不完全支持CSS3 ...
- 尝试通过DeepSeek来优化提高WordPress网站的打开速度,还真有效!
头图由AI生成 嗯,用户问的是WordPress网站如何优化打开速度.首先,我需要考虑用户可能的背景.他们可能是一个WordPress网站的管理员或者拥有者,发现网站加载速度不够快,想要进行优化.用户 ...