1. get()
public V get ( Object key) {
Node< K, V> [ ] tab; Node< K, V> e, p; int n, eh; K ek;
int h = spread ( key. hashCode ( ) ) ;
if ( ( tab = table) != null && ( n = tab. length) > 0 &&
( e = tabAt ( tab, ( n - 1 ) & h) ) != null) {
if ( ( eh = e. hash) == h) {
if ( ( ek = e. key) == key || ( ek != null && key. equals ( ek) ) )
return e. val;
}
else if ( eh < 0 )
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;
}
}
return null;
}
2. getOrDefault
获取到则返回 value,获取不到(即 null) 返回指定的默认值
public V getOrDefault ( Object key, V defaultValue) {
Vv;
return ( v = get ( key) ) == null ? defaultValue : v;
}
3. compute
给定 key 值找到节点 p,与 remappingFunction(key, value) 生成的 val 值
p 为 null,val 为null :没有改变,相当于无需进行操作 p 为 null,val 不为null :新添加节点 Node(key, val) p 不为 null,val 为null :相当于删除 key 对应的节点 p 不为 null,val 不为null :相当于更换 p 的 value 值
public V compute ( K key,
BiFunction< ? super K, ? super V, ? extends V > remappingFunction) {
if ( key == null || remappingFunction == null)
throw new NullPointerException ( ) ;
int h = spread ( key. hashCode ( ) ) ;
V val = null;
int delta = 0 ;
int binCount = 0 ;
for ( Node< K, V> [ ] tab = table; ; ) {
Node< K, V> f; int n, i, fh;
if ( tab == null || ( n = tab. length) == 0 )
tab = initTable ( ) ;
else if ( ( f = tabAt ( tab, i = ( n - 1 ) & h) ) == null) {
Node< K, V> r = new ReservationNode < K, V> ( ) ;
synchronized ( r) {
if ( casTabAt ( tab, i, null, r) ) {
binCount = 1 ;
Node< K, V> node = null;
try {
if ( ( val = remappingFunction. apply ( key, null) ) != null) {
delta = 1 ;
node = new Node < K, V> ( h, key, val, null) ;
}
} finally {
setTabAt ( tab, i, node) ;
}
}
}
if ( binCount != 0 )
break ;
}
else if ( ( fh = f. hash) == MOVED)
tab = helpTransfer ( tab, f) ;
else {
synchronized ( f) {
if ( tabAt ( tab, i) == f) {
if ( fh >= 0 ) {
binCount = 1 ;
for ( Node< K, V> e = f, pred = null; ; ++ binCount) {
K ek;
if ( e. hash == h &&
( ( ek = e. key) == key ||
( ek != null && key. equals ( ek) ) ) ) {
val = remappingFunction. apply ( key, e. val) ;
if ( val != null)
e. val = val;
else {
delta = - 1 ;
Node< K, V> en = e. next;
if ( pred != null)
pred. next = en;
else
setTabAt ( tab, i, en) ;
}
break ;
}
pred = e;
if ( ( e = e. next) == null) {
val = remappingFunction. apply ( key, null) ;
if ( val != null) {
delta = 1 ;
pred. next =
new Node < K, V> ( h, key, val, null) ;
}
break ;
}
}
}
else if ( f instanceof TreeBin ) {
binCount = 1 ;
TreeBin< K, V> t = ( TreeBin< K, V> ) f;
TreeNode< K, V> r, p;
if ( ( r = t. root) != null)
p = r. findTreeNode ( h, key, null) ;
else
p = null;
V pv = ( p == null) ? null : p. val;
val = remappingFunction. apply ( key, pv) ;
if ( val != null) {
if ( p != null)
p. val = val;
else {
delta = 1 ;
t. putTreeVal ( h, key, val) ;
}
}
else if ( p != null) {
delta = - 1 ;
if ( t. removeTreeNode ( p) )
setTabAt ( tab, i, untreeify ( t. first) ) ;
}
}
}
}
if ( binCount != 0 ) {
if ( binCount >= TREEIFY_THRESHOLD)
treeifyBin ( tab, i) ;
break ;
}
}
}
if ( delta != 0 )
addCount ( ( long ) delta, binCount) ;
return val;
}
4. computeIfAbsent
给定 key 值找到节点 p,与 remappingFunction(key) 生成的 val 值
p 为 null,val 为null :没有改变,相当于无需进行操作 p 为 null,val 不为null :新添加节点 Node(key, val) p 不为 null,val 为null :返回 val 值 p 不为 null,val 不为null :返回 val 值
public V computeIfAbsent ( K key, Function< ? super K, ? extends V > mappingFunction) {
if ( key == null || mappingFunction == null)
throw new NullPointerException ( ) ;
int h = spread ( key. hashCode ( ) ) ;
V val = null;
int binCount = 0 ;
for ( Node< K, V> [ ] tab = table; ; ) {
Node< K, V> f; int n, i, fh;
if ( tab == null || ( n = tab. length) == 0 )
tab = initTable ( ) ;
else if ( ( f = tabAt ( tab, i = ( n - 1 ) & h) ) == null) {
Node< K, V> r = new ReservationNode < K, V> ( ) ;
synchronized ( r) {
if ( casTabAt ( tab, i, null, r) ) {
binCount = 1 ;
Node< K, V> node = null;
try {
if ( ( val = mappingFunction. apply ( key) ) != null)
node = new Node < K, V> ( h, key, val, null) ;
} finally {
setTabAt ( tab, i, node) ;
}
}
}
if ( binCount != 0 )
break ;
}
else if ( ( fh = f. hash) == MOVED)
tab = helpTransfer ( tab, f) ;
else {
boolean added = false ;
synchronized ( f) {
if ( tabAt ( tab, i) == f) {
if ( fh >= 0 ) {
binCount = 1 ;
for ( Node< K, V> e = f; ; ++ binCount) {
K ek; V ev;
if ( e. hash == h &&
( ( ek = e. key) == key ||
( ek != null && key. equals ( ek) ) ) ) {
val = e. val;
break ;
}
Node< K, V> pred = e;
if ( ( e = e. next) == null) {
if ( ( val = mappingFunction. apply ( key) ) != null) {
added = true ;
pred. next = new Node < K, V> ( h, key, val, null) ;
}
break ;
}
}
}
else if ( f instanceof TreeBin ) {
binCount = 2 ;
TreeBin< K, V> t = ( TreeBin< K, V> ) f;
TreeNode< K, V> r, p;
if ( ( r = t. root) != null &&
( p = r. findTreeNode ( h, key, null) ) != null)
val = p. val;
else if ( ( val = mappingFunction. apply ( key) ) != null) {
added = true ;
t. putTreeVal ( h, key, val) ;
}
}
}
}
if ( binCount != 0 ) {
if ( binCount >= TREEIFY_THRESHOLD)
treeifyBin ( tab, i) ;
if ( ! added)
return val;
break ;
}
}
}
if ( val != null)
addCount ( 1 L, binCount) ;
return val;
}
5. computeIfPresent
给定 key 值找到节点 p,与 remappingFunction(key,value) 生成的 val 值
p 为 null :不进行任何操作 p 不为 null,val 为null :删除 p 节点 p 不为 null,val 不为null :替换 p 节点的 value 值
public V computeIfPresent ( K key, BiFunction< ? super K, ? super V, ? extends V > remappingFunction) {
if ( key == null || remappingFunction == null)
throw new NullPointerException ( ) ;
int h = spread ( key. hashCode ( ) ) ;
V val = null;
int delta = 0 ;
int binCount = 0 ;
for ( Node< K, V> [ ] tab = table; ; ) {
Node< K, V> f; int n, i, fh;
if ( tab == null || ( n = tab. length) == 0 )
tab = initTable ( ) ;
else if ( ( f = tabAt ( tab, i = ( n - 1 ) & h) ) == null)
break ;
else if ( ( fh = f. hash) == MOVED)
tab = helpTransfer ( tab, f) ;
else {
synchronized ( f) {
if ( tabAt ( tab, i) == f) {
if ( fh >= 0 ) {
binCount = 1 ;
for ( Node< K, V> e = f, pred = null; ; ++ binCount) {
K ek;
if ( e. hash == h &&
( ( ek = e. key) == key ||
( ek != null && key. equals ( ek) ) ) ) {
val = remappingFunction. apply ( key, e. val) ;
if ( val != null)
e. val = val;
else {
delta = - 1 ;
Node< K, V> en = e. next;
if ( pred != null)
pred. next = en;
else
setTabAt ( tab, i, en) ;
}
break ;
}
pred = e;
if ( ( e = e. next) == null)
break ;
}
}
else if ( f instanceof TreeBin ) {
binCount = 2 ;
TreeBin< K, V> t = ( TreeBin< K, V> ) f;
TreeNode< K, V> r, p;
if ( ( r = t. root) != null &&
( p = r. findTreeNode ( h, key, null) ) != null) {
val = remappingFunction. apply ( key, p. val) ;
if ( val != null)
p. val = val;
else {
delta = - 1 ;
if ( t. removeTreeNode ( p) )
setTabAt ( tab, i, untreeify ( t. first) ) ;
}
}
}
}
}
if ( binCount != 0 )
break ;
}
}
if ( delta != 0 )
addCount ( ( long ) delta, binCount) ;
return val;
}
6. 小总结
import java. util. concurrent. ConcurrentHashMap;
public class ConcurrentHashMapTest03 {
public static void main ( String[ ] args) throws Exception {
ConcurrentHashMap< Integer, Integer> concurrentHashMap = new ConcurrentHashMap < > ( ) ;
for ( int i = 1 ; i <= 10 ; i++ ) {
concurrentHashMap. put ( i, i) ;
}
System. out. println ( "now concurrentHashMap: " + concurrentHashMap) ;
System. out. println ( "concurrentHashMap.get(1): " + concurrentHashMap. get ( 1 ) ) ;
System. out. println ( "concurrentHashMap.get(11): " + concurrentHashMap. get ( 11 ) ) ;
System. out. println ( "concurrentHashMap.getOrDefault(1, 10): " + concurrentHashMap. getOrDefault ( 1 , 10 ) ) ;
System. out. println ( "concurrentHashMap.getOrDefault(11, 11): " + concurrentHashMap. getOrDefault ( 11 , 11 ) ) ;
System. out. println ( "now concurrentHashMap: " + concurrentHashMap) ;
System. out. println ( "=================== compute =======================" ) ;
System. out. println ( "concurrentHashMap.compute(1, (key, value) -> value * 10): " + concurrentHashMap. compute ( 1 , ( key, value) - > value * 10 ) ) ;
System. out. println ( "concurrentHashMap.compute(2, (key, value) -> null): " + concurrentHashMap. compute ( 2 , ( key, value) - > null) ) ;
System. out. println ( "concurrentHashMap.compute(11, (key, value) -> 110): " + concurrentHashMap. compute ( 11 , ( key, value) - > 110 ) ) ;
System. out. println ( "concurrentHashMap.compute(12, (key, value) -> null): " + concurrentHashMap. compute ( 12 , ( key, value) - > null) ) ;
System. out. println ( "now concurrentHashMap: " + concurrentHashMap) ;
System. out. println ( "=================== computeIfAbsent =======================" ) ;
System. out. println ( "concurrentHashMap.computeIfAbsent(3, (key) -> 30): " + concurrentHashMap. computeIfAbsent ( 3 , ( key) - > 30 ) ) ;
System. out. println ( "concurrentHashMap.computeIfAbsent(4, (key) -> null): " + concurrentHashMap. computeIfAbsent ( 4 , ( key) - > null) ) ;
System. out. println ( "concurrentHashMap.computeIfAbsent(13, (key) -> 130): " + concurrentHashMap. computeIfAbsent ( 13 , ( key) - > 130 ) ) ;
System. out. println ( "concurrentHashMap.computeIfAbsent(14, (key) -> null): " + concurrentHashMap. computeIfAbsent ( 14 , ( key) - > null) ) ;
System. out. println ( "now concurrentHashMap: " + concurrentHashMap) ;
System. out. println ( "=================== computeIfPresent =======================" ) ;
System. out. println ( "concurrentHashMap.computeIfPresent(5, (key, value) -> value * 10): " + concurrentHashMap. computeIfPresent ( 5 ( key, value) - > value * 10 ) ) ;
System. out. println ( "concurrentHashMap.computeIfPresent(6, (key, value) -> null): " + concurrentHashMap. computeIfPresent ( 6 , ( key, value) - > null) ) ;
System. out. println ( "concurrentHashMap.computeIfPresent(15, (key, value) -> value * 10): " + concurrentHashMap. computeIfPresent ( 15 , ( key, value) - > value * 10 ) ) ;
System. out. println ( "concurrentHashMap.computeIfPresent(16, (key, value) -> null): " + concurrentHashMap. computeIfPresent ( 16 , ( key, value) - > null) ) ;
System. out. println ( "now concurrentHashMap: " + concurrentHashMap) ;
}
}