面试 ---集合(三)ConcurrentHashMap原理分析

news/2024/11/29 2:38:59/

https://my.oschina.net/hosee/blog/639352

https://blog.csdn.net/u011328417/article/details/79284730

http://www.importnew.com/28263.html

http://www.importnew.com/22007.html

HashTable是一个线程安全的类,它使用synchronized来锁住整张Hash表来实现线程安全,即每次锁住整张表让线程独占。ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。它使用了多个锁来控制对hash表的不同部分进行的修改。ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的Hashtable,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。

ConcurrentHashMap使用分段锁技术,将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问,能够实现真正的并发访问

在JDK1.7中,ConcurrentHashMap的数据结构是由一个Segment数组和多个HashEntry组成

Segment数组的意义就是将一个大的table分割成多个小的table来进行加锁,Segment数组中每一个元素就是一把锁,每一个Segment元素存储的是HashEntry数组+链表,这个和HashMap的数据存储结构一样。 
默认ConcurrentHashMap长度是16。

从图中可以看到,ConcurrentHashMap内部分为很多个Segment,每一个Segment拥有一把锁,然后每个Segment(继承ReentrantLock)

static final class Segment<K,V> extends ReentrantLock implements Serializable

Segment继承了ReentrantLock,表明每个segment都可以当做一个锁。(ReentrantLock前文已经提到,不了解的话就把当做synchronized的替代者吧)这样对每个segment中的数据需要同步操作的话都是使用每个segment容器对象自身的锁来实现。只有对全局需要改变时锁定的是所有的segment。

Segment下面包含很多个HashEntry列表数组。对于一个key,需要经过三次(为什么要hash三次下文会详细讲解)hash操作,才能最终定位这个元素的位置,这三次hash分别为:

  1. 对于一个key,先进行一次hash操作,得到hash值h1,也即h1 = hash1(key);
  2. 将得到的h1的高几位进行第二次hash,得到hash值h2,也即h2 = hash2(h1高几位),通过h2能够确定该元素的放在哪个Segment;
  3. 将得到的h1进行第三次hash,得到hash值h3,也即h3 = hash3(h1),通过h3能够确定该元素放置在哪个HashEntry。

ConcurrentHashMap中主要实体类就是三个:ConcurrentHashMap(整个Hash表),Segment(桶),HashEntry(节点),对应上面的图可以看出之间的关系


http://www.ppmy.cn/news/662176.html

相关文章

SEE

SSE是英特尔提出的即MMX之后新一代&#xff08;当然是几年前了&#xff09;CPU指令集&#xff0c;最早应用在PIII系列CPU上。现在已经得到了Intel PIII、P4、Celeon、Xeon、AMD Athlon、duron等系列CPU的支持。而更新的SSE2指令集仅得到了P4系列CPU的支持&#xff0c;这也是为什…

ConcurrentHashMap原理分析

ConcurrentHashMap实现原理及源码分析 一、ConcurrentHashMap跟HashMap&#xff0c;HashTable的对比 1. HashMap不是线程安全&#xff1a; 在并发环境下&#xff0c;可能会形成环状链表&#xff08;扩容时可能造成&#xff0c;具体原因自行百度google或查看源码分析&#xf…

hashids

它的原理就是从数字经过一个加盐(salted)算法产生一个哈希(hash)字符串。这样算法就是通过混淆使结果具有不可预测性&#xff0c;而唯一性依然由数字本身来达成&#xff0c;从而得到(类似 youtube 里的)足够短&#xff0c;不可预测且唯一的 ID。 安装&#xff1a; npm instal…

whois查询实现

可以从 https://www.iana.org/ 免费查询 很多库都是从这个网页查询出来的 也可以拿到各 顶级域名的whoisServer&#xff0c;查询对应43端口&#xff0c;拿到whois信息 命令查询 linux 安装whois 工具 whois (domain) 即可查询

java中父进程与子进程

转自&#xff1a;https://my.oschina.net/hosee/blog/509557 以前在学习操作系统的时候&#xff0c;一直记得的父线程死后&#xff0c;子线程也消失了。然而今天在查资料中&#xff0c;发现有点疑惑&#xff0c;在此记录一下。 Java编写的程序都运行在Java虚拟机&#xff08;…

Home...

见了Tencent&#xff0c;IBM&#xff0c;Skyworth&#xff0c;ZTE后&#xff0c;一脸的激动。 路没什么两样&#xff0c;人倒是区别蛮大&#xff0c; 呵呵&#xff0c;号称中国硅谷。我来描述一下这个地方&#xff1a; --------------------- 公车按路段收费&#xff0c;整天给…

Java中的父线程与子线程

转自: https://my.oschina.net/hosee/blog/509557 以前在学习操作系统的时候&#xff0c;一直记得的父线程死后&#xff0c;子线程也消失了。然而今天在查资料中&#xff0c;发现有点疑惑&#xff0c;在此记录一下。 Java编写的程序都运行在Java虚拟机&#xff08;JVM&#x…

JAVA锁的膨胀过程

为什么80%的码农都做不了架构师&#xff1f;>>> 首先简单说下先偏向锁、轻量级锁、重量级锁三者各自的应用场景&#xff1a; 偏向锁&#xff1a;只有一个线程进入临界区&#xff1b;轻量级锁&#xff1a;多个线程交替进入临界区&#xff1b;重量级锁&#xff1a;多…