zoukankan      html  css  js  c++  java
  • 面试必问-几种线程安全的Map解析

    HashMap线程安全的吗?

    Java中平时用的最多的Map集合就是HashMap了,它是线程不安全的。

    看下面两个场景:

    1、当用在方法内的局部变量时,局部变量属于当前线程级别的变量,其他线程访问不了,所以这时也不存在线程安全不安全的问题了。

    2、当用在单例对象成员变量的时候呢?这时候多个线程过来访问的就是同一个HashMap了,对同个HashMap操作这时候就存在线程安全的问题了。

    线程安全的Map

    为了避免出现场景2的线程安全的问题,不能使用HashMap作为成员变量,要寻求使用线程安全的Map,下面来总结下有哪些线程安全的Map呢?

    1、HashTable

    private Map<String, Object> map = new Hashtable<>();

    来看看HashTable的源码

    HashTable的get/put方法都被synchronized关键字修饰,说明它们是方法级别阻塞的,它们占用共享资源锁,所以导致同时只能一个线程操作get或者put,而且get/put操作不能同时执行,所以这种同步的集合效率非常低,一般不建议使用这个集合。

    2、SynchronizedMap

    private Map<String, Object> map = Collections.synchronizedMap(new HashMap<String, Object>());

    这种是直接使用工具类里面的方法创建SynchronizedMap,把传入进行的HashMap对象进行了包装同步而已,来看看它的源码。

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

    3、ConcurrentHashMap - 推荐

    private Map<String, Object> map = new ConcurrentHashMap<>();

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

    虽然实现起来很复杂,但使用起来也是非常简单的,在java面试中问的频率也非常高,最重要的是性能要比上面两种同步方式要快太多,推荐使用。

    推荐去我的博客阅读更多:

    1.Java JVM、集合、多线程、新特性系列教程

    2.Spring MVC、Spring Boot、Spring Cloud 系列教程

    3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

    4.Java、后端、架构、阿里巴巴等大厂最新面试题

    觉得不错,别忘了点赞+转发哦!

  • 相关阅读:
    学习 swift (1)
    Sbulime Text 2 修改选中字符串的颜色
    js string 和 json 互转
    Mac OSX sublime text2 各种快捷键
    webstorm keymap
    python http post json
    node.js async 几个函数
    python 爬图 helloworld
    合服导致 globalserver 起不来的问题
    ssh 登陆 端口转发
  • 原文地址:https://www.cnblogs.com/javastack/p/12854625.html
Copyright © 2011-2022 走看看