//构造方法 publicConcurrentHashMap(int initialCapacity){ if (initialCapacity < 0)//判断参数是否合法 thrownew IllegalArgumentException(); int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY ://最大为2^30 tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));//根据参数调整table的大小 this.sizeCtl = cap;//获取容量 //ConcurrentHashMap在构造函数中只会初始化sizeCtl值,并不会直接初始化table } //调整table的大小 privatestaticfinalinttableSizeFor(int c){//返回一个大于输入参数且最小的为2的n次幂的数。 int n = c - 1; n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; }
final V putVal(K key, V value, boolean onlyIfAbsent){ if (key == null || value == null) thrownew NullPointerException(); int hash = spread(key.hashCode()); int binCount = 0; for (Node<K,V>[] tab = table;;) { Node<K,V> f; int n, i, fh; K fk; V fv; if (tab == null || (n = tab.length) == 0)//判断table还未初始化 tab = initTable();//初始化table elseif ((f = tabAt(tab, i = (n - 1) & hash)) == null) { if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value))) break; // no lock when adding to empty bin } ...省略一部分源码 } }
privatefinal Node<K,V>[] initTable() { Node<K,V>[] tab; int sc; while ((tab = table) == null || tab.length == 0) { //如果一个线程发现sizeCtl<0,意味着另外的线程执行CAS操作成功,当前线程只需要让出cpu时间片, //由于sizeCtl是volatile的,保证了顺序性和可见性 if ((sc = sizeCtl) < 0)//sc保存了sizeCtl的值 Thread.yield(); // lost initialization race; just spin elseif (U.compareAndSetInt(this, SIZECTL, sc, -1)) {//cas操作判断并置为-1 try { if ((tab = table) == null || tab.length == 0) { int n = (sc > 0) ? sc : DEFAULT_CAPACITY;//DEFAULT_CAPACITY = 16,若没有参数则大小默认为16 @SuppressWarnings("unchecked") Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n]; table = tab = nt; sc = n - (n >>> 2); } } finally { sizeCtl = sc; } break; } } return tab; }