HashMap为什么不安全?哪里不安全?

链接:https://www.jianshu.com/p/e2f75c8cce01

问题一:说一说Map?

先看一个Map继承类图
HashMap为什么不安全?哪里不安全?_第1张图片

  • Map是一个接口,我们常用的实现类有HashMap、LinkedHashMap、TreeMap,HashTable。

  • HashMap 根据key的hashCode值来找到一个桶的位置来保存value,需要注意的是,HashMap不保证遍历的顺序和插入的顺序是一致的。HashMap允许有一条记录的key为null,但是对值是否为null不做要求。

  • HashTable类 是线程安全的,它使用synchronize来做线程安全全局只有一把锁,在线程竞争比较激烈的情况下hashtable的效率是比较低下的。因为当一个线程访问hashtable的同步方法时,其他线程再次尝试访问的时候,会进入阻塞或者轮询状态,比如当线程1使用put进行元素添加的时候,线程2不但不能使用put来添加元素,而且不能使用get获取元素。所以,竞争会越来越激烈。

  • 相比之下,ConcurrentHashMap 使用了分段锁技术来提高了并发度,不在同一段的数据互相不影响,多个线程对多个不同的段的操作是不会相互影响的。每个段使用一把锁。所以在需要线程安全的业务场景下,推荐使用ConcurrentHashMap,而HashTable不建议在新的代码中使用,如果需要线程安全,则使用ConcurrentHashMap,否则使用HashMap就足够了。

  • LinkedHashMap 属于HashMap的子类,与HashMap的区别在于LinkedHashMap保存了记录插入的顺序

  • TreeMap 实现了SortedMap接口,TreeMap有能力对插入的记录根据key排序,默认按照升序排序,也可以自定义比较强,在使用TreeMap的时候,key应当实现Comparable


HashMap为什么不安全?哪里不安全?

  • HashMap之所以线程不安全,就是resize这里出的问题。
  • HashMap在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发resize扩容操作,扩容操作中,在多线程的环境下,存在同时其他的元素也在进行扩容过程的put操作,可能会导致 原来的链表形成一个循环链表, 然后进行get操作时 就可能引起死循环(cpu100%)。

你可能感兴趣的:(JavaSE)