ConcurrentHashMap 的工做原理及代码实现:java
相比于1.7版本,它作了两个改进数组
一、取消了segment分段设计,直接使用Node数组来保存数据,而且采用Node数组元素做为锁来实现每一行数据进行加锁来进一步减小并发冲突的几率安全
二、将本来数组+单向链表的数据结构变动为了数组+单向链表+红黑树的结构。为何要引入红黑树呢?在正常状况下,key hash以后若是可以很均匀的分散在数组中,那么table数组中的每一个队列的长度主要为0或者1.可是实际状况下,仍是会存在一些队列长度过长的状况。若是还采用单向列表方式,那么查询某个节点的时间复杂度就变为O(n); 所以对于队列长度超过8的列表,JDK1.8采用了红黑树的结构,那么查询的时间复杂度就会下降到O(logN),能够提高查找的性能; 数据结构
JDK1.8中,Segment类只有在序列化和反序列化时才会被用到;并发
抛弃了原有的 Segment 分段锁,而采用了 CAS + synchronized
来保证并发安全性。性能
transient volatile Node<K,V>[] table;
static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; volatile V val; volatile Node<K,V> next; Node(int hash, K key, V val, Node<K,V> next) { this.hash = hash; this.key = key; this.val = val; this.next = next; } }
1. Node类this
Node类主要用于存储具体键值对,其子类有ForwardingNode、ReservationNode、TreeNode和TreeBin四个子类。四个子类具体的代码在以后的具体例子中进行分析讲解。spa
2. Traverser类设计
Traverser类主要用于遍历操做,其子类有BaseIterator、KeySpliterator、ValueSpliterator、EntrySpliterator四个类,BaseIterator用于遍历操做。KeySplitertor、ValueSpliterator、EntrySpliterator则用于键、值、键值对的划分。code
3. CollectionView类
CollectionView抽象类主要定义了视图操做,其子类KeySetView、ValueSetView、EntrySetView分别表示键视图、值视图、键值对视图。对视图都可以进行操做。
4. Segment类
Segment类在JDK1.8中与以前的版本的JDK做用存在很大的差异,JDK1.8下,其在普通的ConcurrentHashMap操做中已经没有失效,其在序列化与反序列化的时候会发挥做用。
5. CounterCell
CounterCell类主要用于对baseCount的计数。
如何统计全部的元素个数:
transient volatile CounterCell[] counterCells; 可方便的计算hashmap中全部元素的个数,性能大大优于jdk1.7中的size()方法