一、概述

HashMap 是非线程安全的,在不考虑性能问题的时候,我们的解决方案有 Hashtable 或者Collections.synchronizedMap(hashMap),这两种方式基本都是对整个 hash 表结构做锁定操作的,这样在锁表的期间,别的线程就需要等待了,无疑性能不高。

二、数据结构

ConcurrentHashMap 数据结构为一个 Segment 数组,Segment 的数据结构为 HashEntry 的数组,而 HashEntry 存的是我们的键值对,可以构成链表。

ConcurrentHashMap 的结构中包含的 Segment 的数组,在默认的并发级别会创建包含 16 个 Segment 对象的数组。每个 Segment 又包含若干个散列表的桶,每个桶是由 HashEntry 链接起来的一个链表。如果 key 能够均匀散列,每个 Segment 大约守护整个散列表桶总数的 1/16。

三、segment

Segment 的类定义为static final class Segment<K,V> extends ReentrantLock implements Serializable。其继承于 ReentrantLock 类,从而使得 Segment 对象可以充当锁的角色。Segment 中包含HashEntry 的数组,其可以守护其包含的若干个桶(HashEntry的数组)。

四、并发put

在 ConcurrentHashMap 中,当执行 put 方法的时候,会需要加锁来完成。

需要注意的是:加锁操作是针对的 hash 值对应的某个 Segment,而不是整个 ConcurrentHashMap。因为 put 操作只是在这个 Segment 中完成,所以并不需要对整个 ConcurrentHashMap 加锁。所以,此时,其他的线程也可以对另外的 Segment 进行 put 操作,因为虽然该 Segment 被锁住了,但其他的 Segment 并没有加锁。同时,读线程并不会因为本线程的加锁而阻塞

ConcurrentHashMap 可以支持 16 个线程执行并发写操作(默认并发级别设置为 16),及任意数量线程的读操作。

五、读操作

无锁,对table进行定义为volatile,满足可见性

六、总结

散列表一般的应用场景是:除了少数插入操作和删除操作外,绝大多数都是读取操作,而且读操作在大多数时候都是成功的。

基于这个前提,ConcurrentHashMap 针对读操作做了大量的优化。通过 HashEntry 对象的不变性用 volatile 型变量协调线程间的内存可见性,使得 大多数时候,读操作不需要加锁就可以正确获得值。

ConcurrentHashMap 是一个并发散列映射表的实现,它允许完全并发的读取,并且支持给定数量的并发更新。相比于 HashTable 和用同步包装器包装的 HashMap(Collections.synchronizedMap(new HashMap())),ConcurrentHashMap 拥有更高的并发性。在 HashTable 和由同步包装器包装的 HashMap 中,使用一个全局的锁来同步不同线程间的并发访问。同一时间点,只能有一个线程持有锁,也就是说在同一时间点,只能有一个线程能访问容器。这虽然保证多线程间的安全并发访问,但同时也导致对容器的访问变成串行化的了。

ConcurrentHashMap 的高并发性主要来自于三个方面:

  • 分离锁实现多个线程间的更深层次的共享访问。
  • HashEntery 对象的不变性来降低执行操作的线程在遍历链表期间对加锁的需求。
  • 通过对同一个 Volatile 变量的写 / 读访问,协调不同线程间读 / 写操作的内存可见性。

使用分离锁,减小了请求 同一个锁的频率。

通过 HashEntery 对象的不变性及对同一个 Volatile 变量的读 / 写来协调内存可见性,使得 读操作大多数时候不需要加锁就能成功获取到需要的值。由于散列映射表在实际应用中大多数操作都是成功的 读操作,所以 2 和 3 既可以减少请求同一个锁的频率,也可以有效减少持有锁的时间。通过减小请求同一个锁的频率和尽量减少持有锁的时间 ,使得 ConcurrentHashMap 的并发性相对于 HashTable 和用同步包装器包装的 HashMap有了质的提高。

容器ConcurrentHashMap原理(学习)的更多相关文章

  1. Spring源码学习之IOC容器实现原理(一)-DefaultListableBeanFactory

    从这个继承体系结构图来看,我们可以发现DefaultListableBeanFactory是第一个非抽象类,非接口类.实际IOC容器.所以这篇博客以DefaultListableBeanFactory ...

  2. IIS原理学习

    IIS 原理学习 首先声明以下内容是我在网上搜索后整理的,在此只是进行记录,以备往后查阅只用. IIS 5.x介绍 IIS 5.x一个显著的特征就是Web Server和真正的ASP.NET Appl ...

  3. Java并发编程:并发容器ConcurrentHashMap

    Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concu ...

  4. ConcurrentHashMap原理

    转载地址:http://www.blogjava.net/xylz/archive/2010/07/20/326661.html 在上一篇中介绍了HashMap的原理,这一节是ConcurrentMa ...

  5. Java并发编程笔记之ConcurrentHashMap原理探究

    在多线程环境下,使用HashMap进行put操作时存在丢失数据的情况,为了避免这种bug的隐患,强烈建议使用ConcurrentHashMap代替HashMap. HashTable是一个线程安全的类 ...

  6. docker容器网络通信原理分析

    概述 自从docker容器出现以来,容器的网络通信就一直是大家关注的焦点,也是生产环境的迫切需求.而容器的网络通信又可以分为两大方面:单主机容器上的相互通信和跨主机的容器相互通信.而本文将分别针对这两 ...

  7. docker容器网络通信原理分析(转)

    概述 自从docker容器出现以来,容器的网络通信就一直是大家关注的焦点,也是生产环境的迫切需求.而容器的网络通信又可以分为两大方面:单主机容器上的相互通信和跨主机的容器相互通信.而本文将分别针对这两 ...

  8. java并发编程的艺术(四)---ConcurrentHashMap原理解析

    本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...

  9. 多线程之并发容器ConcurrentHashMap

    这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步 ...

随机推荐

  1. python 1-1模块介绍和使用

    1. 什么是模块 1.1 模块就是一系列功能的集合体 1.1.1 模块有三种来源 1.内置的模块 2.第三方的模块 3.自定义模块 1.1.2 模块的格式: 1.使用Python编写的.py文件 2. ...

  2. virtualbox虚拟机桥接方式网络设置

    一.编辑网卡 cd   /etc/sysconfig/network-scripts 查看本地win10ip及子网掩码: 如果查看到的ip不是192开头的,可以手动设置为192开头的ip 2.设置虚拟 ...

  3. centos6 用户登陆管理

    查看当前登陆有哪些用户,在做什么 [root@web01 ~]# w :: up :, users, load average: 0.00, 0.00, 0.00 USER TTY FROM LOGI ...

  4. 树莓派 -- 输入设备驱动 (key) 续2: 转载 Setting up a GPIO-Button “keyboard” on a Raspberry Pi

    使用device-tree (DT) overlay应该是更方便的方法: http://blog.gegg.us/2017/01/setting-up-a-gpio-button-keyboard-o ...

  5. 树莓派 - 通过sysfs操控GPIO

    点亮或熄灭LED 硬件上,一个LED灯接在pi的Pin-25.  该引脚为BCM的GPIO26 $ gpio readall +-----+-----+---------+------+---+--- ...

  6. eclipse perl配置

    先下载jdk,如果jdk装的是32位,eclipse也要下载32位的,64位也是一样.我用的是jdk7 64位. 下载eclipse,去官网上下载最新的http://www.eclipse.org/d ...

  7. Python之套接字

    Python之套接字 客户端Client/服务端Server架构: 1.硬件C/S架构 2.软件C/S架构 OSI4层:4层里有五层,五层里又有7层. 四层---------五层--------七层 ...

  8. C语言的移位操作符及位运算

    C语言的移位操作符 位移位运算符是将数据看成二进制数,对其进行向左或向右移动若干位的运算.位移位运算符分为左移和右移两种,均为双目运算符.第一运算对象是移位对象,第二个运算对象是所移的二进制位数. 位 ...

  9. iar修改包含路径的方法

  10. BNUOJ 6023 畅通工程续

    畅通工程续 Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 1874 ...