En primer lugar, la aplicación java código fuente adjunto 8
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 / ** Implementación de suelta y putIfAbsent * / 2 final de V putVal (clave K, el valor V, boolean onlyIfAbsent) { 3 si (clave == nula || valor == nula ) arrojar nueva NullPointerException (); 4 int de hash = propagación (key.hashCode ()); 5 int binCount = 0 ; 6 para (Nodo <K, V> [] tab = mesa ;;) { 7 Nodo <K, V> f; int n, i, fh; 8 Si (pestaña == nula|| (= n-tab.length) == 0) // primer uso, toda la tabla es nulo 9. Tab = initTable (); 10 el otro IF . ((F = Tabat (Tab, i = (n- 1) el hash y)) == nula ) { 11. IF (casTabAt (Tab, I, nula , 12 es nuevo nuevo el nodo <K, V> (el hash, Key, valor nulo ))) 13 es PAUSA ; // NO Lock al agregar para vaciar bin 14 } 15 el otro iF ((FH = f.hash) == desplazado) // cuando el valor de hash nodo de -1, representante de la ForwardingNode nodo, los nodos posteriores que necesitan ser transferidos 16 = Tab helpTransfer (Tab, F); . 17 la otra cosa { 18 es V OLDVAL = nulo ; . 19 el sincronizado (F) { 20 es SI (Tabat (Tab, I) == F) { // la zona caliente para obtener el código correcto se ejecuta de nuevo, primero asegurar registrada antes de la i-ésimo nodo no ha cambiado (es decir, no se migraron de distancia) 21 es SI (FH> = 0) { // asegurarse de que el valor de dispersión del nodo actual representa un nodo normal (nodo otro auxiliar, tal ForwardingNode, TreeBin, ReservationNode) 22 es BinCount = 1. ; 23 es para (el nodo <K, V> E = F ;; ++ BinCount) { 24 K EK; 25 IF(El hash de e.hash == && 26 es ((EK = e.key) == || Clave 27 (EK! = Nula && key.equals (EK)))) { // El análisis del nodo de destino se basa en la difusión y el mismo valor hash (de la misma clave o equivalente referencia clave) 28 OLDVAL = Eval; 29 IF (! onlyIfAbsent) 30 Eval = valor; 31 es PAUSA ; 32 } 33 es el nodo <K, V> Pred = e; 34 es si((E = e.next) == nula ) { // si el nodo actual alcanza el final de la lista, append el nuevo elemento 35 pred.next = nuevo nuevo el Nodo <K, V> (el hash, Key, 36 valor, nulo ) ; 37 [ PAUSA ; 38 es } 39 } 40 } 41 es la más iF (F la instanceof TreeBin) { // cuando fh es menor que 0, y es -2, cuando el tipo de elemento TreeBin 42 es el nodo <K, V>pag; 43 binCount = 2 ; 44 si ((p = ((TreeBin <K, V> ) f) .putTreeVal (hash de clave,, 45 valor)) =! Nulo ) { 46 OLDVAL = p.val; 47 si (! OnlyIfAbsent) 48 p.val = valor; 49 } 50 } 51 } 52 } 53 si (binCount! = 0) { 54 es SI (BinCount> = TREEIFY_THRESHOLD) // cuando los elementos de inserción, la lista del número de nodos es igual a una sola ranura es mayor que 8, un árbol rojo-negro de la ranura 55 treeifyBin (Tab, I); 56 es SI (OLDVAL =! nulo ) 57 es volver OLDVAL; 58 PAUSA ; 59 } 60 } 61 es } 62 es addCount (1 l , BinCount); 63 es el retorno nulo ; 64 }
una