java 数组 分段_JUC入门系列(四)-ConcurrentHashMap 锁分段机制

一、JUC简介

Java 5.0 提供了java.util.concurrent(简称JUC)包,在此包中增加了在并发编程中很常见的实用工具类,用于定义类似于编程的自定义子系统,包括线程池、异步IO和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文的Collection实现等。

二、HashMap 和 Hashtable 的问题

HashMap 线程不安全;Hashtable因为使用了synchronized修饰方法而导致执行效率不高。

三、ConcurrentHashMap

Java5.0 在 java.util.concurrent 包中提供了多种并发容器类来改进同步容器的性能。

ConcurrentHashMap 同步容器类是 Java 5 增加的一个线程安全的哈希表。对于多线程的操作,介于 HashMap 与Hashtable之间。内部采用“锁分段”机制替代Hashtable的独占锁,进而提高性能。

此包中还提供了设计用于多线程上下文中的Collection实现:ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet、CopyOnWriteArrayList 和 CopyOnWriteArraySet。当期望许多线程访问一个给定collection时,ConcurrentHashMap 通常优于同步的 HashMap,ConcurrentSkipListMap 通常由于同步的TreeMap。当期望的读数和遍历远远大于列表的更新数时,CopyOnWriteArrayList 优于同步的 ArrayList。

四、ConcurrentHashMap的实现

JDK1.7及之前的 ConcurrentHashMap 使用 锁分段机制实现,JDK1.8则使用 数组+链表+红黑树数据结构和CAS原子操作实现。

JDK 1.5 - 1.7

Hashtable 之所以效率低下,主要是因为其实现使用了synchronized 关键字对 put 等操作进行加锁,而 synchronized 关键字加锁是对整个对象加锁,也就是说在进行put等修改Hashtable的操作时,锁住了整个Hash表,从而使得其效率低下。因此在JDK1.5~1.7版本,Java使用分段锁机制实现ConcurrentHashMap。锁分段机制的ConcurrentHashMap 模拟图如下:

3d2137534e6390f8b79919f4fc7a8e43.png

ConcurrentHashMap找那个定义了一个Segment[]数组来讲Hash表分段存储,从而实现分段加锁;而每个Segment元素则与HashMap结构类似,其包含了一个HashEntry数组,用来存储Key/Value对。Segment继承了ReetrantLock,表示Segment是一个可重入锁,因此ConcurrentHashMap通过可重入锁对每个分段进行加锁。

JDK 1.8

JDK 1.8之前,ConcurrentHashMap采用锁分段机制,其最大并发度受Segment的个数限制。因此JDK 1.8 摒弃了这种设计,而是选择了与HashMap类似的数组+链表+红黑树的方式实现,而加锁则采用CAS + synchronized 实现。

关于CAS的说明,可简单参考 JUC入门系列(二)-CAS算法

JDK 1.8 的ConcurrentHashMap的数据结构比JDK 1.7 之前的要简单的多,其使用的是HashMap一样的数据结构:数组+链表+红黑树。ConcurrentHashMap 中包含一个table数组,其类型是一个Node数组;而Node数组是一个继承自Map.Entry 的链表,而当这个链表结构中的数组大于8,则将数据结构升级为TreeBin类型的红黑树结构。另外,JDK 1.8 的ConcurrentHashMap中还包含一个重要的属性,sizeCtl,它是一个控制标识符,不同的值代表不同的意思:为0时,表示hash还没初始化;为正数时表示初始化或下一次扩容的大小,相当于一个阈值。即:如果hash表的实际大小 >= sizeCtl,则进行扩容,默认情况下为当前ConcurrentHashMap容量的0.75倍;而如果sizeCtl 为 -1,表示正在进行初始化操作。为 -N 时,则表示有 N-1 个线程正在进行扩容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值