hashmap,concurrentHashmap,arrayList比较

发布时间 2023-04-05 21:59:36作者: 人在代码在

一.安全性比较

1.hashmap是线程不安全的,concurrentHashmap是线程安全的

JDK1.7只要记住会造成死循环数据丢失。

JDK1.8在多线程环境下会发生数据覆盖。

JDK1.8 中,由于多线程对HashMap进行put操作,调用了HashMap#putVal(),具体原因:假设两个线程A、B都在进行put操作,并且hash函数计算出的插入下标是相同的,当线程A执行完第六行代码后由于时间片耗尽导致被挂起,而线程B得到时间片后在该下标处插入了元素,完成了正常的插入,然后线程A获得时间片,由于之前已经进行了hash碰撞的判断,所有此时不会再进行判断,而是直接进行插入,这就导致了线程B插入的数据被线程A覆盖了,从而线程不安全。

2、如何使HashMap在多线程情况下进行线程安全操作?
使用 Collections.synchronizedMap(map),包装成同步Map,原理就是在HashMap的所有方法上synchronized。

例如:Collections.SynchronizedMap#get()

public V get(Object key) {
synchronized (mutex) {
return m.get(key);
}
}

3.concurrentHashmap为什么是线程安全的

currenthashmap的线程安全保证主要通过synchronized,volatile,cas三种机制共同处理来保证整体的线程安全,线程安全问题主要出在put和扩容两方面。

put的时候会保证当前数组在该列的hash处已经锁定,并且没有出在扩容的前提下进行put,保证只有一个线程在该列put

扩容问题是通过cas和锁老保证的,首先会new出一个二倍大小的数组rehash不涉及原来数组,且对扩容列加锁并且可以实现并发扩容,将以扩完的列设置为不可用,最后都扩容完之后将新数组替换到table处。