CHM是Hash的线程安全版本,实现方式是数组+cas+synchronized,从分段锁替换成这种模式,设计者的初衷是下面几点:

    • 加入分段锁会浪费内存空间;
    • map竞争同一个锁的概率低,每次操作加锁会降低效率;

    如果新增元素,会对对应桶的头结点加锁。

    1. V oldVal = null;
    2. synchronized (f) {
    3. if (tabAt(tab, i) == f) {
    4. if (fh >= 0) {
    5. binCount = 1;
    6. for (Node<K,V> e = f;; ++binCount) {
    7. K ek;
    8. if (e.hash == hash &&
    9. ((ek = e.key) == key ||
    10. (ek != null && key.equals(ek)))) {
    11. oldVal = e.val;
    12. if (!onlyIfAbsent)
    13. e.val = value;
    14. break;
    15. }
    16. Node<K,V> pred = e;
    17. if ((e = e.next) == null) {
    18. pred.next = new Node<K,V>(hash, key, value);
    19. break;
    20. }
    21. }
    22. }
    23. else if (f instanceof TreeBin) {
    24. Node<K,V> p;
    25. binCount = 2;
    26. if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
    27. value)) != null) {
    28. oldVal = p.val;
    29. if (!onlyIfAbsent)
    30. p.val = value;
    31. }
    32. }
    33. else if (f instanceof ReservationNode)
    34. throw new IllegalStateException("Recursive update");
    35. }
    36. }