ConcurrentHashMap(JDK1.8)为什么要放弃Segment

今天看到一篇博客:jdk1.8的HashMap和ConcurrentHashMap,我想起了前段时间面试的一个问题:ConcurrentHashMap(JDK1.8)为什么要使用synchronized而不是可重入锁?

我想从下面几个角度讨论这个问题:

  1. 锁的粒度 
    首先锁的粒度并没有变粗,甚至变得更细了。每当扩容一次,ConcurrentHashMap的并发度就扩大一倍。
  2. Hash冲突 
    JDK1.7中,ConcurrentHashMap从过二次hash的方式(Segment -> HashEntry)能够快速的找到查找的元素。在1.8中通过链表加红黑树的形式弥补了put、get时的性能差距。
  3. 扩容 
    JDK1.8中,在ConcurrentHashmap进行扩容时,其他线程可以通过检测数组中的节点决定是否对这条链表(红黑树)进行扩容,减小了扩容的粒度,提高了扩容的效率。


下面是我对面试中的那个问题的一下看法:

为什么是synchronized,而不是可重入锁 
1. 减少内存开销 
假设使用可重入锁来获得同步支持,那么每个节点都需要通过继承AQS来获得同步支持。但并不是每个节点都需要获得同步支持的,只有链表的头节点(红黑树的根节点)需要同步,这无疑带来了巨大内存浪费。 
2. 获得JVM的支持 
可重入锁毕竟是API这个级别的,后续的性能优化空间很小。 
synchronized则是JVM直接支持的,JVM能够在运行时作出相应的优化措施:锁粗化、锁消除、锁自旋等等。这就使得synchronized能够随着JDK版本的升级而不改动代码的前提下获得性能上的提升。

原文地址:https://www.cnblogs.com/wfq9330/p/9606472.html

时间: 2024-08-01 00:37:25

ConcurrentHashMap(JDK1.8)为什么要放弃Segment的相关文章

多线程-ConcurrentHashMap(JDK1.8)

前言 HashMap非线程安全的,HashTable是线程安全的,所有涉及到多线程操作的都加上了synchronized关键字来锁住整个table,这就意味着所有的线程都在竞争一把锁,在多线程的环境下,它是安全的,但是无疑效率低下的. ConcurrentHashMap(JDK1.7) 在JDK1.7中,ConcurrentHashMap的数据结构是由一个Segment数组和多个HashEntry组成的,如图: Segment数组的意义就是将一个大的table分割成多个小的table来进行加锁,

ConcurrentHashMap源码分析(JDK1.7和1.8对比)

一.ConcurrentHashMap简介 并发编程大师Doug Lea开发的并发容器之一.ConcurrentHashMap是线程安全且高效的HashMap,在HashMap的基础上增加了线程安全,当然结构方面也有所改变. 为什么要使用ConcurrentHashMap? 1.多线程环境下,HashMap会处于不安全状态.例如put操作可能会引起程序死循环,Cpu占有率达百分百,原因是多线程会导致HashMap的Entry链表形成环形数据结构,如此一来,他的next结点将永不为空,就会产生死循

Java并发编程总结4——ConcurrentHashMap在jdk1.8中的改进

一.简单回顾ConcurrentHashMap在jdk1.7中的设计 先简单看下ConcurrentHashMap类在jdk1.7中的设计,其基本结构如图所示: 每一个segment都是一个HashEntry<K,V>[] table, table中的每一个元素本质上都是一个HashEntry的单向队列.比如table[3]为首节点,table[3]->next为节点1,之后为节点2,依次类推. public class ConcurrentHashMap<K, V> ext

Java并发编程总结4——ConcurrentHashMap在jdk1.8中的改进(转)

一.简单回顾ConcurrentHashMap在jdk1.7中的设计 先简单看下ConcurrentHashMap类在jdk1.7中的设计,其基本结构如图所示: 每一个segment都是一个HashEntry<K,V>[] table, table中的每一个元素本质上都是一个HashEntry的单向队列.比如table[3]为首节点,table[3]->next为节点1,之后为节点2,依次类推. public class ConcurrentHashMap<K, V> ext

转 jdk1.5新特性 ConcurrentHashMap

ConcurrentHashMap特点:效率比Hashtable高,并发性比hashmap好.结合了两者的特点. 集合是编程中最常用的数据结构.而谈到并发,几乎总是离不开集合这类高级数据结构的支持.比如两个线程需要同时访问一个中间临界区(Queue),比如常会 用缓存作为外部文件的副本(HashMap).这篇文章主要分析jdk1.5的3种并发集合类型 (concurrent,copyonright,queue)中的ConcurrentHashMap,让我们从原理上细致的了解它们,能够让我们在深

ConcurrentHashMap 1.8为什么要使用CAS+Synchronized取代Segment+ReentrantLock

通过源码可以看出 使用 CAS + synchronized 方式时 加锁的对象是每个链条的头结点,也就是 锁定 的是冲突的链表,所以再次提高了并发度,并发度等于链表的条数或者说 桶的数量.那为什么sement 不把段的大小设置为一个桶的,因为在高并发的情况下如果 ReentrantLock 发生冲突会直接挂起,开销非常大,而synchorinzed 有自旋锁机制,可以很大程度上降低这种开销. 下文转自:https://www.cnblogs.com/yangfeiORfeiyang/p/969

jdk1.8的HashMap和ConcurrentHashMap

原文地址:https://my.oschina.net/pingpangkuangmo/blog/817973 本文针对jdk1.8的ConcurrentHashMap 1 1.8的HashMap设计 1.1 整体概览 HashMap采用的是数组+链表+红黑树的形式. 数组是可以扩容的,链表也是转化为红黑树的,这2种方式都可以承载更多的数据. 用户可以设置的参数:初始总容量默认16,默认的加载因子0.75 初始的数组个数默认是16 容量X加载因子=阈值 一旦目前容量超过该阈值,则执行扩容操作.

Concurrency of ConcurrentHashMap

转自 :http://cache.baiducontent.com/  良辰美景奈何天 并发编程实践中,ConcurrentHashMap是一个经常被使用的数据结构,相比于Hashtable以及Collections.synchronizedMap(),ConcurrentHashMap在线程安全的基础上提供了更好的写并发能力,但同时降低了对读一致性的要求(这点好像CAP理论啊 O(∩_∩)O).ConcurrentHashMap的设计与实现非常精巧,大量的利用了volatile,final,C

并发-ConcurrentHashMap

ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对HashMap的实现原理还不甚了解,可参考我的另一篇文章HashMap实现原理及源码分析),ConcurrentHashMap在并发编程的场景中使用频率非常之高,本文就来分析下ConcurrentHashMap的实现原理,并对其实现原理进行分析(JDK1.7). ConcurrentHashMap实现原理 众所周知,哈希表是中非常高效,复杂度为O(1)的数据结构,在Java开发中,我们最常见到最