HashMap不是线程安全的,那么应该用什么集合好呢

HashMap一般有两个使用场景:

(1)用在方法内的局部变量时,由于局部变量属于当前线程级别的变量,其他线程不能够访问,所以此时也就不存在线程安全问题。

(2)当用在单例对象成员变量时:这时候多个线程过来访问的就是同一个HashMap了,对同一个HashMap操作时就要考虑线程安全问题


为了避免该线程安全问题,不能使用HashMap作为成员变量,要寻求安全的Map,有如下几个选择:

(1)Hash Table

privateMapmap = newHashtable<>() 

Hash Table源码中发现,其get/put方法均被synchronized关键词修饰(该关键词修饰代表这个方法加上了同步锁,相当于任意线程运行到该方法时,首先应检查有没有其它线程在使用该方法,有的话要等待上一个线程使用完毕后,当前线程才能使用)

正因如此,Hash Table的线程安全是基于方法级阻塞制的,它们占用共享资源,所以导致同时只能有一个线程操作get或put,并且get和put操作不能同时执行,所以这种同步的集合效率很低,一般不建议使用这个集合。

(2)SynchronizedMap

privateMapmap = Collections.synchronizedMap(newHashMap())

这种事直接使用工具类里面的方法创建synchronizedMap,把传入的HashMap对象进行了包装而已。

这个同步方式实现也比较简单,看出SynchronizedMap的实现方式是加了个对象锁,每次对HashMap的操作都要先获取这个mutex对象才能进入,故而性能也不会比HashTable好到哪去,也不建议使用。

(3)ConcurrentHashMap

privateMapmap = new ConcurrentHashMap<>()

这个实现结构最复杂,但同时也是效率最高最推荐使用的线程安全的Map,每个版本实现方式不一。Jdk8之前是使用分段加锁的方式,分成16个桶,每次只加锁其中一个桶,而jdk8又加入了红黑树和CAS算法来实现。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • HashMap 是 Java 面试必考的知识点,面试官从这个小知识点就可以了解我们对 Java 基础的掌握程度。网...
    野狗子嗷嗷嗷阅读 11,658评论 9 107
  • 占坑,准备码一篇做数据可视化的,大部分来自网络资源。 回复来自2018年的flag(笑哭)请回答2018,我在两年...
    赵晨西西西西阅读 4,138评论 0 2
  • 我想摘下您脸上的皱纹 编成渔网 网住时光那条鱼 我想摸平您手上的老茧 画一朵花 吐露至真的爱 我想闻闻您抽旱烟的味...
    风不值阅读 832评论 0 1
  • 过去,总觉得未来很好,过去比不上未来; 当未来变成了现在, 总觉得还是过去美好,现在比不上过去; 不是现在比不上过...
    厄念阅读 1,202评论 0 0