原创

HashMap的几个关键点

1.HashMap设计原理

既能享有数组的快速查询,又享有双向链表的快速增加删除,于是出现了hashMap

2.HashMap的底层数据结构?

数组和链表,JDK1.8之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。

3.HashMap的长度为什么是2的幂次方?

为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀,因为计算机是2进制,hashmap获取索引id的算法为:(h = key.hashCode()) ^ (h >>> 16)采取的是位运算,而非取模或者除等运算,性能和效率会高很多

4.HashMap多线程操作导致死循环问题?

在多线程下,进行put操作会导致HashMap死循环,原因在于HashMap的扩容resize()方法。由于扩容是新建一个数组,复制原数据到数组。由于数组下标挂有链表,所以需要复制链表,但是多线程操作有可能导致环形链表

代码:jdk1.6可以出现,jdk1.8已经修复

public class HashMapConcurrentProblem extends Thread {
private static Map<Integer, Integer> map = new HashMap<Integer, Integer>();
private static AtomicInteger at = new AtomicInteger(0);
@Override
public void run() {
while (at.get() < 1000000) {
map.put(at.get(), at.get());
at.incrementAndGet();
}
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Thread thread = new HashMapConcurrentProblem();
thread.start();
}
}
}


正文到此结束
本文目录