java并发编程(十六)-并发容器之ConcurrentHashMap (JDK1.8中原理和实现)

与1.7相比的重大变化

  1. 取消了segment数组,直接用table保存数据,锁的粒度更小,减少并发冲突的概率。
  2. 存储数据时采用了链表+红黑树的形式,纯链表的形式时间复杂度为O(n),红黑树则为O(logn),性能提升很大。什么时候链表转红黑树?当key值相等的元素形成的链表中元素个数超过8个的时候。

主要数据结构和关键变量

Node类存放实际的key和value值。

sizeCtl:

负数:表示进行初始化或者扩容,-1表示正在初始化,-N,表示有N-1个线程正在进行扩容

正数:0 表示还没有被初始化,>0的数,初始化或者是下一次进行扩容的阈值

TreeNode 用在红黑树,表示树的节点, TreeBin是实际放在table数组中的,代表了这个红黑树的根。

初始化做了什么事?

只是给成员变量赋值,put时进行实际数组的填充

 

在get和put操作中,是如何快速定位元素放在哪个位置的?

java并发编程(十六)-并发容器之ConcurrentHashMap (JDK1.8中原理和实现)_第1张图片

java并发编程(十六)-并发容器之ConcurrentHashMap (JDK1.8中原理和实现)_第2张图片

get()方法

java并发编程(十六)-并发容器之ConcurrentHashMap (JDK1.8中原理和实现)_第3张图片

put()方法

数组的实际初始化

java并发编程(十六)-并发容器之ConcurrentHashMap (JDK1.8中原理和实现)_第4张图片

java并发编程(十六)-并发容器之ConcurrentHashMap (JDK1.8中原理和实现)_第5张图片

java并发编程(十六)-并发容器之ConcurrentHashMap (JDK1.8中原理和实现)_第6张图片

java并发编程(十六)-并发容器之ConcurrentHashMap (JDK1.8中原理和实现)_第7张图片

扩容操作

transfer()方法进行实际的扩容操作,table大小也是翻倍的形式,有一个并发扩容的机制。

size方法

估计的大概数量,不是精确数量

一致性

弱一致

你可能感兴趣的:(多线程,并发编程)