| 失效链接处理 |
|
为什么 HashMap 是线程不安全的?
相关截图:
![]() 主要内容:
先搞清楚 HashMap 长什么样
HashMap 说白了就是一张表:底下是数组,数组每个格子叫「桶」。桶里可能是空的,也可能挂着一条链表。JDK 8 之后,链表太长还会升级成红黑树,不过这不影响我们今天要讲的事情。
你 put 一个键值对,它大概会走这几步:算 hash、找到落在哪个桶、看看桶里有没有相同的 key、没有就挂上去、人多了还得扩容。
单线程用起来很香,读写都快。麻烦出在:这些步骤都不是原子的。中间任何一个环节被另一个线程插一脚,结果就不可控了。
坑一:两个线程一起 put,数据会丢
这是最好复现的一个问题。两个线程往同一个 HashMap 里塞数据,最后 size() 经常对不上。
原因其实很朴素:两个线程可能算完 hash 后,都觉得「这个位置是空的」,于是各自把节点写进去。后写的那个会把先写的盖掉,被盖掉的那条数据就消失了。size 的自增也不是原子操作,两边同时 size++,加了两次看起来只加了一次。
|


苏公网安备 32061202001004号
