PUT方法
graph TD
A[开始 putVal 方法] --> B{key 或 value 为 null?}
B -->|是| C[抛出 NullPointerException]
B -->|否| D[计算 hash 值]
D --> E{table 为 null 或长度为 0?}
E -->|是| F[初始化 table]
E -->|否| G{目标桶为空?}
F --> G
G -->|是| H{CAS 插入新节点成功?}
H -->|是| I[跳出循环]
H -->|否| G
G -->|否| J{节点 hash 值为 MOVED?}
J -->|是| K[协助扩容 transfer]
K --> E
J -->|否| L{onlyIfAbsent 为 true 且 key 已存在?}
L -->|是| M[返回旧值]
L -->|否| N[对头节点加 synchronized 锁]
N --> O{头节点 hash 值 >= 0?}
O -->|是| P[遍历链表]
P --> Q{找到相同 key?}
Q -->|是| R{onlyIfAbsent 为 false?}
R -->|是| S[更新值]
R -->|否| T[保持原值]
Q -->|否| U[在链表尾部插入新节点]
O -->|否| V{节点是 TreeBin?}
V -->|是| W[调用 putTreeVal 插入到红黑树]
W --> X{插入成功且 onlyIfAbsent 为 false?}
X -->|是| Y[更新值]
X -->|否| Z[保持原值]
V -->|否| AA{节点是 ReservationNode?}
AA -->|是| AB[抛出 IllegalStateException]
AA -->|否| AC[其他情况]
AC --> AD{binCount != 0?}
AD -->|是| AE{binCount >= TREEIFY_THRESHOLD?}
AE -->|是| AF[转换为红黑树 treeifyBin]
AE -->|否| AG[不转换]
AF --> AH{oldVal != null?}
AG --> AH
AH -->|是| AI[返回旧值]
AH -->|否| AJ[跳出循环]
AJ --> AK[增加计数 addCount]
AK --> AL[返回 null]
I --> AK
M --> AM[结束]
AI --> AM
AL --> AM
C --> AM
AB --> AM
T --> AD
S --> AD
U --> AD
Z --> AD
Y --> AD
Comments NOTHING