HashMap线程安全面试题(含答案)

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(newHashMap<String, Object>());

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

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

3、ConcurrentHashMap - 推荐

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

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

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

相关推荐
IT枫斗者枫哥13 分钟前
CompletableFuture失败后返回空列表:异常没了,业务含义也变了
java·后端
知识搬运临时工24 分钟前
一个模板把 AEM 拖进 Full GC 死亡螺旋:300% CPU、7 GB 堆、310 万行堆栈
java·aws
熊猫钓鱼>_>26 分钟前
鸿蒙 PC 三方库适配复盘:libfvad 1.0 —— 把 WebRTC VAD 做成能装进采集链路的静态库
服务器·开发语言·华为·harmonyos·openharmony·适配·鸿蒙pc
用户4329359280528 分钟前
CoAP还是MQTT:1万只Cat.1水表三个月带宽续航实测
java
知守观38 分钟前
多模块架构演进:横向分层 vs 纵向领域,13 个真实项目的切分对照
java·后端·微服务
Ai-_Man39 分钟前
Coze扣子还是不可以导出左侧所有对话,只能点进去单条内容导出,方法不对吗?
开发语言·人工智能·ai·小程序·1024程序员节
raindayinrain1 小时前
c++设计模式
开发语言·c++·设计模式
Java成神之路-1 小时前
Java String 为什么不可变?和 HashMap 到底有什么关系?
java
hiahiahia1231 小时前
Streaming Model Output
开发语言·前端
paopaokaka_luck1 小时前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts