/** * Creates a new, empty map with a default initial capacity (16), * load factor (0.75) and concurrencyLevel (16). */ publicConcurrentHashMap() { this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL); }
其中调用了有参构造函数,传递了三个参数:
/** * The default initial capacity for this table, * used when not otherwise specified in a constructor. */ staticfinalintDEFAULT_INITIAL_CAPACITY=16;
/** * The default load factor for this table, used when not * otherwise specified in a constructor. */ staticfinalfloatDEFAULT_LOAD_FACTOR=0.75f;
/** * The default concurrency level for this table, used when not * otherwise specified in a constructor. */ staticfinalintDEFAULT_CONCURRENCY_LEVEL=16;
/** * Maps the specified key to the specified value in this table. * Neither the key nor the value can be null. */ @SuppressWarnings("unchecked") public V put(K key, V value) { Segment<K,V> s; if (value == null) thrownewNullPointerException(); inthash= hash(key.hashCode()); // hash值无符号右移segmentShift(默认初始化28位),然后与segmentMask(=15)做与运算 // => 将高几位与segmentMask做与运算 intj= (hash >>> segmentShift) & segmentMask; if ((s = (Segment<K,V>)UNSAFE.getObject // nonvolatile; recheck (segments, (j << SSHIFT) + SBASE)) == null) // in ensureSegment // 如果查找到的Segment为空,初始化 s = ensureSegment(j); return s.put(key, hash, value, false); }
初始化Segment
/** * Returns the segment for the given index, creating it and * recording in segment table (via CAS) if not already present. */ @SuppressWarnings("unchecked") private Segment<K,V> ensureSegment(int k) { final Segment<K,V>[] ss = this.segments; longu= (k << SSHIFT) + SBASE; // raw offset Segment<K,V> seg; // 判断u位置的Segment是否为null if ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u)) == null) { // 以Segment[0]作为原型初始化 Segment<K,V> proto = ss[0]; // use segment 0 as prototype intcap= proto.table.length; floatlf= proto.loadFactor; intthreshold= (int)(cap * lf); HashEntry<K,V>[] tab = (HashEntry<K,V>[])newHashEntry[cap]; // 再次检查u位置的Segment是否为null,因为此时可能有其他线程进行了操作 if ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u)) == null) { // recheck Segment<K,V> s = newSegment<K,V>(lf, threshold, tab); // CAS自旋检查u位置的Segment是否为null while ((seg = (Segment<K,V>)UNSAFE.getObjectVolatile(ss, u)) == null) { // 使用CAS赋值,只会成功一次 if (UNSAFE.compareAndSwapObject(ss, u, null, seg = s)) break; } } } return seg; }
privatevoidrehash(HashEntry<K,V> node) { /* * Reclassify nodes in each list to new table. Because we * are using power-of-two expansion, the elements from * each bin must either stay at same index, or move with a * power of two offset. We eliminate unnecessary node * creation by catching cases where old nodes can be * reused because their next fields won't change. * Statistically, at the default threshold, only about * one-sixth of them need cloning when a table * doubles. The nodes they replace will be garbage * collectable as soon as they are no longer referenced by * any reader thread that may be in the midst of * concurrently traversing table. Entry accesses use plain * array indexing because they are followed by volatile * table write. */ HashEntry<K,V>[] oldTable = table; intoldCapacity= oldTable.length; intnewCapacity= oldCapacity << 1; threshold = (int)(newCapacity * loadFactor); HashEntry<K,V>[] newTable = (HashEntry<K,V>[]) newHashEntry[newCapacity]; // 新掩码,默认2,扩容后是4,再减去1就是3,二进制就是11 intsizeMask= newCapacity - 1; for (inti=0; i < oldCapacity ; i++) { HashEntry<K,V> e = oldTable[i]; if (e != null) { HashEntry<K,V> next = e.next; // 计算新的位置,新的位置只可能是不变或者是 旧位置+旧容量 intidx= e.hash & sizeMask; if (next == null) // Single node on list // 当前位置不是链表,只是一个元素,直接赋值 newTable[idx] = e; else { // Reuse consecutive sequence at same slot // 是链表 HashEntry<K,V> lastRun = e; intlastIdx= idx; // 遍历结束后,lastRun 后面的元素位置都是相同的 for (HashEntry<K,V> last = next; last != null; last = last.next) { intk= last.hash & sizeMask; if (k != lastIdx) { lastIdx = k; lastRun = last; } } // lastRun 后面的元素位置都是相同的,直接作为链表赋值到新位置。 newTable[lastIdx] = lastRun; // Clone remaining nodes for (HashEntry<K,V> p = e; p != lastRun; p = p.next) { // 遍历剩余元素,头插法到指定的k位置 Vv= p.value; inth= p.hash; intk= h & sizeMask; HashEntry<K,V> n = newTable[k]; newTable[k] = newHashEntry<K,V>(h, p.key, v, n); } } } } // 头插法插入新的节点 intnodeIndex= node.hash & sizeMask; // add the new node node.setNext(newTable[nodeIndex]); newTable[nodeIndex] = node; table = newTable; }
上述代码中的第一个 for
是为了寻找这样一个节点,这个节点后面的所有next节点的新位置都是不变的,然后把这个作为一个链表赋值到新位置。第二个
for 循环是为了把剩余的元素通过头插法插入到指定位置链表。
get
get方法的逻辑:
计算得到key的存放位置
遍历指定位置查找相同的key的value值
/** * Returns the value to which the specified key is mapped, * or {@code null} if this map contains no mapping for the key. */ public V get(Object key) { Segment<K,V> s; // manually integrate access methods to reduce overhead HashEntry<K,V>[] tab; inth= hash(key.hashCode()); longu= (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE; // 计算得到Key的存放位置 if ((s = (Segment<K,V>)UNSAFE.getObjectVolatile(segments, u)) != null && (tab = s.table) != null) { for (HashEntry<K,V> e = (HashEntry<K,V>) UNSAFE.getObjectVolatile (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE); e != null; e = e.next) { // 如果是链表,遍历查找相同key的value K k; if ((k = e.key) == key || (e.hash == h && key.equals(k))) return e.value; } } returnnull; }
/** * Table initialization and resizing control. When negative, the * table is being initialized or resized: -1 for initialization, * else -(1 + the number of active resizing threads). Otherwise, * when table is null, holds the initial table size to use upon * creation, or 0 for default. After initialization, holds the * next element count value upon which to resize the table. */ privatetransientvolatileint sizeCtl; /** * Initializes table, using the size recorded in sizeCtl. */ privatefinal Node<K,V>[] initTable() { Node<K,V>[] tab; int sc; while ((tab = table) == null || tab.length == 0) { // 如果sizeCtl < 0,说明存在其他线程执行CAS成功,正在执行初始化操作 if ((sc = sizeCtl) < 0) // 主动让出CPU使用权 Thread.yield(); // lost initialization race; just spin elseif (U.compareAndSwapInt(this, SIZECTL, sc, -1)) { try { if ((tab = table) == null || tab.length == 0) { intn= (sc > 0) ? sc : DEFAULT_CAPACITY; @SuppressWarnings("unchecked") Node<K,V>[] nt = (Node<K,V>[])newNode<?,?>[n]; table = tab = nt; sc = n - (n >>> 2); } } finally { sizeCtl = sc; } break; } } return tab; }
/** * Returns the value to which the specified key is mapped, * or {@code null} if this map contains no mapping for the key. * * <p>More formally, if this map contains a mapping from a key * {@code k} to a value {@code v} such that {@code key.equals(k)}, * then this method returns {@code v}; otherwise it returns * {@code null}. (There can be at most one such mapping.) */ public V get(Object key) { Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek; // 计算key的hash值 inth= spread(key.hashCode()); if ((tab = table) != null && (n = tab.length) > 0 && (e = tabAt(tab, (n - 1) & h)) != null) { // 指定位置元素存在,头节点hash值相同 if ((eh = e.hash) == h) { if ((ek = e.key) == key || (ek != null && key.equals(ek))) // key的hash值相等、key值相等,直接返回元素的value return e.val; } elseif (eh < 0) // 头节点hash值小于0,说明正在扩容或者是红黑树,find查找 return (p = e.find(h, key)) != null ? p.val : null; while ((e = e.next) != null) { // 是链表,遍历查找 if (e.hash == h && ((ek = e.key) == key || (ek != null && key.equals(ek)))) return e.val; } } returnnull; }