原文网址:Java之HashMap系列--ConcurrentHashMap的原理_IT利刃出鞘的博客-****博客
简介
本文介绍Java中的ConcurrentHashMap的原理。
JDK7与JDK8区别
项 |
JDK1.7 |
JDK1.8 |
实现方式 |
HashMap(数组 + 链表) |
HashMap(数组 + 链表 + 红黑树) |
保证线程安全的方式 |
使用ReentrantLock 对 Segment同步 |
读操作:volatile; 写操作:synchronized + CAS |
粒度 |
对需要进行数据操作的Segment加锁 |
对每个桶(数组项)加锁 |
JDK8原理概述
概述
JDK8中ConcurrentHashMap结构基本上和HashMap一样,采用了HashMap(数组 + 链表 + 红黑树) + synchronized + CAS 的实现方式来设计。读操作使用volatile,写操作使用synchronized 和CAS。
CAS:在判断数组中当前位置为null的时候,使用CAS把这个新的Node写入数组中对应的位置。
synchronized :当数组中的指定位置不为空时,通过加锁来添加这个节点进入数组(链表<8)或者是红黑树(链表>=8)
JDK8中采用的是Node(放弃了Segment)。Node:保存key,value及key的hash值的数据结构。其中value和next都用volatile修饰,保证并发的可见性。
class Node<K,V>implements <K,V> {
final int hash;
final K key;
volatile V val;
volatile Node<K,V> next;
//... 省略部分代码
}
JDK8源码分析
put
线程访问哈希表的bucket时,使用 sychronized关键字,防止多个线程同时操作同一个 bucket(即锁住bucket)。如果该结点的 hash值不少于0,则遍历链表更新节点或插入新节点;如果该节点是TreeBin类型的节点,说明是红黑树结构,则通过putTreeVal方法往红黑树中插入节点;更新了节点数量,还要考虑扩容和链表转红黑树。
上边是文章的部分内容,为便于维护,全文已迁移到此网址:Java-ConcurrentHashMap的原理 - 自学精灵