1. public V put(K key, V value) {
    2. Segment<K,V> s;
    3. if (value == null)
    4. throw new NullPointerException();
    5. int hash = hash(key);
    6. // 计算出 segment 下标
    7. int j = (hash >>> segmentShift) & segmentMask;
    8. // 获得 segment 对象, 判断是否为 null, 是则创建该 segment
    9. if ((s = (Segment<K,V>)UNSAFE.getObject
    10. (segments, (j << SSHIFT) + SBASE)) == null) {
    11. // 这时不能确定是否真的为 null, 因为其它线程也发现该 segment 为 null,
    12. // 因此在 ensureSegment 里用 cas 方式保证该 segment 安全性
    13. s = ensureSegment(j);
    14. }
    15. // 进入 segment 的put 流程
    16. return s.put(key, hash, value, false);
    17. }

    segment 继承了可重入锁(ReentrantLock),它的 put 方法为

    1. final V put(K key, int hash, V value, boolean onlyIfAbsent) {
    2. // 尝试加锁
    3. HashEntry<K,V> node = tryLock() ? null :
    4. // 如果不成功, 进入 scanAndLockForPut 流程
    5. // 如果是多核 cpu 最多 tryLock 64 次, 进入 lock 流程
    6. // 在尝试期间, 还可以顺便看该节点在链表中有没有, 如果没有顺便创建出来
    7. scanAndLockForPut(key, hash, value);
    8. // 执行到这里 segment 已经被成功加锁, 可以安全执行
    9. V oldValue;
    10. try {
    11. HashEntry<K,V>[] tab = table;
    12. int index = (tab.length - 1) & hash;
    13. HashEntry<K,V> first = entryAt(tab, index);
    14. for (HashEntry<K,V> e = first;;) {
    15. if (e != null) {
    16. // 更新
    17. K k;
    18. if ((k = e.key) == key ||
    19. (e.hash == hash && key.equals(k))) {
    20. oldValue = e.value;
    21. if (!onlyIfAbsent) {
    22. e.value = value;
    23. ++modCount;
    24. }
    25. break;
    26. }
    27. e = e.next;
    28. }
    29. else {
    30. // 新增
    31. // 1) 之前等待锁时, node 已经被创建, next 指向链表头
    32. if (node != null)
    33. node.setNext(first);
    34. else
    35. // 2) 创建新 node
    36. node = new HashEntry<K,V>(hash, key, value, first);
    37. int c = count + 1;
    38. // 3) 扩容
    39. if (c > threshold && tab.length < MAXIMUM_CAPACITY)
    40. rehash(node);
    41. else
    42. // 将 node 作为链表头
    43. setEntryAt(tab, index, node);
    44. ++modCount;
    45. count = c;
    46. oldValue = null;
    47. break;
    48. }
    49. }
    50. } finally {
    51. unlock();
    52. }
    53. return oldValue; }