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面试中问的频率也非常高,最重要的是性能要比上面两种同步方式要快太多,推荐使用。

相关推荐
程序媛小果6 分钟前
基于java+SpringBoot+Vue的宠物咖啡馆平台设计与实现
java·vue.js·spring boot
追风林11 分钟前
mac m1 docker本地部署canal 监听mysql的binglog日志
java·docker·mac
芒果披萨25 分钟前
El表达式和JSTL
java·el
q5673152326 分钟前
在 Bash 中获取 Python 模块变量列
开发语言·python·bash
许野平1 小时前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
也无晴也无风雨1 小时前
在JS中, 0 == [0] 吗
开发语言·javascript
狂奔solar1 小时前
yelp数据集上识别潜在的热门商家
开发语言·python
duration~1 小时前
Maven随笔
java·maven
zmgst1 小时前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
跃ZHD1 小时前
前后端分离,Jackson,Long精度丢失
java