Yige

Yige

Build

ConcurrentHashMap和Hashtable

ConcurrentHashMap && Hashtable#

ConcurrentHashMap 是如何实现线程安全的 ?#

JDK1.5 中的实现#

使用Segment(extends ReentrantLock)来实现
使用分段锁技术, 将 ConcurrentHashMap 将锁一段一段的存储,然后给每一段数据配一把锁(segment),当一个线程占用一把锁(segment)访问其中一段数据的时候,其他段的数据也能被其它的线程访问,默认分配 16 个 segment, 默认比 Hashtable 效率提高 16 倍

JDK1.8 中的实现#

采用CASsynchronized来保证并发安全
JDK8 中的实现也是锁分离的思想,它把锁分的比segment(JDK1.5)更细一些,只要 hash 不冲突,就不会出现并发获得锁的情况。它首先使用无锁操作CAS插入头结点,如果插入失败,说明已经有别的线程插入头结点了,再次循环进行操作 (类似自旋锁)。如果头结点已经存在,则通过synchronized获得头结点锁,进行后续的操作,性能比 segment 分段锁又再次提升

Hashtable#

Hashtable 也是线程安全的的一种键值对的数据结构

和 HashMap 比较:#

  1. Hashtable 在 JDK1.0 就有了,HashMap 产生于 JDK1.2
  2. Hashtable 继承自 Dictionary 类 (已废弃), HashMap 是继承自 AbstractMap 类
  3. Hashtable 既不支持 Null key 也不支持 Null value,HashMap 中,null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null
  4. Hashtable 是线程安全的,它的每个方法中都加入了 Synchronize 方法,HashMap 不是线程安全的
  5. Hashtable、HashMap 都使用了 Iterator,不过由于历史原因,Hashtable 还使用了 Enumeration 的方式
  6. Hashtable 默认的初始大小为 11,之后每次扩充,容量变为原来的 2n+1。HashMap 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍
  7. 计算 hash 值的方法不同: Hashtable 直接使用对象的 hashCode, 而 HashMap 还使用了扰动函数处理

和 Collections.synchronizedMap () 的区别#

synchronizedMap是 Collections 的私有静态内部类,可以通过Collecitons.synchronizedMap(Map)方法获取一个 synchronizedMap 向上转型为 Map 对象

对比分析:

  • Hashtable 是对所有方法通过 synchronized 关键字加锁
  • 有一个 Object 类型 mutext 互斥对象成员,对存在线程安全的方法使用 synchronize 关键字对 mutex 进行加锁
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。