标签:return table capacity new 函数 compare res rac swa
java1.8中的ConcurrentHashMap做了非常大的改动,整个数据结构都发生了变化,已经不存在segment了。所以要好好重新查看下源码。这篇博客是逐步更行的,看一点写一点。
首先看一个很重要的参数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倍。
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 }
标签:return table capacity new 函数 compare res rac swa
原文地址:https://www.cnblogs.com/JMLiu/p/8747834.html