HashMap多线程put引起null
HashMap是线程非安全的,引起get(key)为null的操作主要来自于HashMap扩容机制。
1、HashMap扩容机制
HashMap默认初始化大小为16,当放入的key数量超过hashMap存放hash(key)指针数组的0.75倍时,将会扩容至指针数组的两倍。
2、HashMap的迁移逻辑
当HashMap扩容时,将会引发数据迁移,迁移hash(key)指针数组,原先的指针将会被新的指针替代,在数据迁移过程中,线程A要扩容至两倍,线程B也要扩容至两倍,线程A将原地址数据迁移至新地址,此时原地址数据被赋值为空,线程B在读取原地址数据时获取到了null,并将null赋值到新地址,因此引起null。
3、HashMap的指针数组闲置问题
所有key经过hash(key)得到的是同一个指针数组地址,此时会造成指针数组闲置 例如:有12个不相同的key,通过hash(key)得到同一个指针数组地址,此时hashMap指针数组只有一个下标被真实使用,其它15个下标未被使用。
4、避坑指南
对于静态资源的全局变量HashMap字段,避免使用多线程操作,若无法避免多线程操作则使用Concurrenthashmap