java1.8中ConcurrentHashMap

java1.8中的ConcurrentHashMap作了很是大的改动,整个数据结构都发生了变化,已经不存在segment了。因此要好好从新查看下源码。这篇博客是逐步更行的,看一点写一点。java

首先看一个很重要的参数sizeCtl,这是一个volatile变量,从名字就能够看出,这是一个大小控制参数。这个参数当CHM的table正在被某个线程正在初始化或者正在resize的时候是负数。当在初始化的时候,是-1;当在resize的时候,值是1(1+正在执行resize操做的线程数量)。在table初始化以前,它是0,初始化以后的其余时间它是下一次table要变成的大小。好神奇有用的一个参数啊。数据结构

private transient volatile int sizeCtl;

接下来看initTable函数。这个函数只有在第一次执行普通操做是才会调用。这个函数第一次展现了sizeCtl的威力。当sizeCtl小于0时,说明有其余线程正在初始化table或者resize table,则主动放弃线程。函数

不然经过CAS把sizeCtl置为-1,这样其余线程在initTable完成以前,看到的sizeCtl都是-1。而后初始化table,而且sizeCtl置为原来(DEFAULT_CAPACITY,为16)的2倍。this

 1 private final Node<K,V>[] initTable() {
 2         Node<K,V>[] tab; int sc;
 3         while ((tab = table) == null || tab.length == 0) {
 4             if ((sc = sizeCtl) < 0)
 5                 Thread.yield(); // lost initialization race; just spin
 6             else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
 7                 try {
 8                     if ((tab = table) == null || tab.length == 0) {
 9                         int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
10                         @SuppressWarnings("unchecked")
11                         Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
12                         table = tab = nt;
13                         sc = n - (n >>> 2);
14                     }
15                 } finally {
16                     sizeCtl = sc;
17                 }
18                 break;
19             }
20         }
21         return tab;
22     }
相关文章
相关标签/搜索