ConcurrentHashMap(JDK1.8)为什么要放弃Segment
今天看到一篇博客:jdk1.8的HashMap和ConcurrentHashMap,我想起了前段时间面试的一个问题:ConcurrentHashMap(JDK1.8)为什么要使用synchronized而不是可重入锁?
我想从下面几个角度讨论这个问题:
- 锁的粒度
首先锁的粒度并没有变粗,甚至变得更细了。每当扩容一次,ConcurrentHashMap的并发度就扩大一倍。 - Hash冲突
JDK1.7中,ConcurrentHashMap从过二次hash的方式(Segment -> HashEntry)能够快速的找到查找的元素。在1.8中通过链表加红黑树的形式弥补了put、get时的性能差距。 - 扩容
JDK1.8中,在ConcurrentHashmap进行扩容时,其他线程可以通过检测数组中的节点决定是否对这条链表(红黑树)进行扩容,减小了扩容的粒度,提高了扩容的效率。
下面是我对面试中的那个问题的一下看法:
为什么是synchronized,而不是可重入锁
1. 减少内存开销
假设使用可重入锁来获得同步支持,那么每个节点都需要通过继承AQS来获得同步支持。但并不是每个节点都需要获得同步支持的,只有链表的头节点(红黑树的根节点)需要同步,这无疑带来了巨大内存浪费。
2. 获得JVM的支持
可重入锁毕竟是API这个级别的,后续的性能优化空间很小。
synchronized则是JVM直接支持的,JVM能够在运行时作出相应的优化措施:锁粗化、锁消除、锁自旋等等。这就使得synchronized能够随着JDK版本的升级而不改动代码的前提下获得性能上的提升。
ConcurrentHashMap(JDK1.8)为什么要放弃Segment的更多相关文章
- 多线程-ConcurrentHashMap(JDK1.8)
前言 HashMap非线程安全的,HashTable是线程安全的,所有涉及到多线程操作的都加上了synchronized关键字来锁住整个table,这就意味着所有的线程都在竞争一把锁,在多线程的环境下 ...
- Java泛型底层源码解析--ConcurrentHashMap(JDK1.7)
1. Concurrent相关历史 JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全 ...
- concurrenthashmap jdk1.8
参考:https://www.jianshu.com/p/c0642afe03e0 CAS的思想很简单:三个参数,一个当前内存值V.旧的预期值A.即将更新的值B,当且仅当预期值A和内存值V相同时,将内 ...
- 6.ConcurrentHashMap jdk1.7
6.1 hash算法 就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所 ...
- ConcurrentHashMap原理分析(1.7与1.8)-put和 get 需要执行两次Hash
ConcurrentHashMap 与HashMap和Hashtable 最大的不同在于:put和 get 两次Hash到达指定的HashEntry,第一次hash到达Segment,第二次到达Seg ...
- ConcurrentHashmap详解以及在JDK1.8的更新
因为hashmap本身是非线程安全的,如果多线程对hashmap进行put操作的话,就会导致死循环等现象.ConcurrentHashMap主要就是为了应对hashmap在并发环境下不安全而诞生的,C ...
- 高并发编程系列:ConcurrentHashMap的实现原理(JDK1.7和JDK1.8)
HashMap.CurrentHashMap 的实现原理基本都是BAT面试必考内容,阿里P8架构师谈:深入探讨HashMap的底层结构.原理.扩容机制深入谈过hashmap的实现原理以及在JDK 1. ...
- java并发系列(七)-----ConcurrentHashMap原理分析(JDK1.8)
JDK1.8的实现已经摒弃了Segment的概念,而是直接用Node数组+链表+红黑树的数据结构来实现,并发控制使用Synchronized和CAS来操作,整个看起来就像是优化过且线程安全的HashM ...
- 转 jdk1.5新特性 ConcurrentHashMap
ConcurrentHashMap特点:效率比Hashtable高,并发性比hashmap好.结合了两者的特点. 集合是编程中最常用的数据结构.而谈到并发,几乎总是离不开集合这类高级数据结构的支持 ...
随机推荐
- Linux 内核版本号查看
简要:1,lsb_release -a 查看linux系统版本 2,uname -a 查看内核版本
- Redmine使用学习
注:陈刚在公司架设了 Redmine xx公司产品档案管理系统,并且与tortoisegit集成了在一起:真心不错!比如git:192.168.10.46,而redmine:192.168.10.46 ...
- C++练习 | 运算符重载练习(字符串相关)
#include <iostream> #include <cmath> #include <cstring> #include <string> #i ...
- Windows 安装Redis程序
一.系统环境 1.硬件系统:Windows7 64位 2.软件环境: Redis 64位 3.2.100.Redis Desktop Manager. 二.Redis安装 下载地址:https://g ...
- FLINK流计算拓扑任务代码分析<一>
我打算以 flink 官方的 例子 <<Monitoring the Wikipedia Edit Stream>> 作为示例,进行 flink 流计算任务 的源码解析说明. ...
- java 8 更优雅的判断是否为空
public static int getLength(String text) { // Java 8 return Optional.ofNullable(text).map(String::le ...
- scRNA-seq genomic analysis pipline
a scRNA-seq genomic anlysis pipline .caret,.dropup>.btn>.caret{border-top-color:#000!important ...
- SAP 直接修改程序的方法
一般项目上都会有这么个神奇的程序,能在测试机和生产机上直接修改程序... REPORT ztest_change. "变量定义 , line() TYPE c, "如果代码中某行大 ...
- Hystrix使用
Hystrix是Netflix开源的一款容错系统,能帮助使用者码出具备强大的容错能力和鲁棒性的程序.如果某程序或class要使用Hystrix,只需简单继承HystrixCommand/Hystrix ...
- 20155218 2006-2007-2 《Java程序设计》第4周学习总结
20155218 2006-2007-2 <Java程序设计>第4周学习总结 教材学习内容总结 重新定义:在继承父类之后,定义与父类中相同的部署方法,但执行的内容不同. 可以使用@over ...