Java 非线程安全的HashMap如何在多线程中使用
Java 非线程安全的HashMap如何在多线程中使用
HashMap 是非线程安全的。在多线程条件下,容易导致死循环,具体表现为CPU使用率100%。因此多线程环境下保证 HashMap 的线程安全性,主要有如下几种方法:
- 使用 java.util.Hashtable 类,此类是线程安全的。
- 使用 java.util.concurrent.ConcurrentHashMap,此类是线程安全的。
- 使用 java.util.Collections.synchronizedMap() 方法包装 HashMap object,得到线程安全的Map,并在此Map上进行操作。
- 自己在程序的关键代码段加锁,保证多线程安全(不推荐)
接下来分析上面列举的几种方法实现并发安全的 HashMap 的原理:
(一)java.util.Hashtable类:
查看该类的源码
- public synchronized V get(Object key) {
- …… //具体的实现省略,请参考 jdk实现
- }
- public synchronized V put(K key, V value) {
- …… //具体的实现省略,请参考 jdk实现
- }
- public synchronized V remove(Object key) {
- …… //具体的实现省略,请参考 jdk实现
- }
上面是 Hashtable 类提供的几个主要方法,包括 get(),put(),remove() 等。注意到每个方法本身都是 synchronized 的,不会出现两个线程同时对数据进行操作的情况,因此保证了线程安全性,但是也大大的降低了执行效率。因此是不推荐的。
(二)使用 java.util.concurrent.ConcurrentHashMap 类:
该类是 HashMap 的线程安全版,与 Hashtable 相比, ConcurrentHashMap 不仅保证了访问的线程安全性,而且在效率上有较大的提高。
ConcurrentHashMap的数据结构如下:
可以看出,相对 HashMap 和 Hashtable, ConcurrentHashMap 增加了Segment 层,每个Segment 原理上等同于一个 Hashtable, ConcurrentHashMap 等同于一个 Segment 的数组。下面是 ConcurrentHashMap 的 put 和 get 方法:
- final Segment<K,V> segmentFor(int hash) {
- return segments[(hash >>> segmentShift) & segmentMask];
- }
- public V put(K key, V value) {
- if (value == null)
- throw new NullPointerException();
- int hash = hash(key.hashCode());
- return segmentFor(hash).put(key, hash, value, false);
- }
- public V get(Object key) {
- int hash = hash(key.hashCode());
- return segmentFor(hash).get(key, hash);
- }
向 ConcurrentHashMap 中插入数据(put) 或者 读取数据(get),首先都要将相应的 Key 映射到对应的 Segment,因此不用锁定整个类, 只要对单个的 Segment 操作进行上锁操作就可以了。理论上如果有 n 个 Segment,那么最多可以同时支持 n 个线程的并发访问,从而大大提高了并发访问的效率。
Java 非线程安全的HashMap如何在多线程中使用的更多相关文章
- 非线程安全的HashMap 和 线程安全的ConcurrentHashMap
在平时开发中,我们经常采用HashMap来作为本地缓存的一种实现方式,将一些如系统变量等数据量比较少的参数保存在HashMap中,并将其作为单例类的一个属性.在系统运行中,使用到这些缓存数据,都可以直 ...
- [Java集合] 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.
注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享. 原文地址: http://blog.csdn.net/zhanger ...
- Java并发基础08. 造成HashMap非线程安全的原因
在前面我的一篇总结(6. 线程范围内共享数据)文章中提到,为了数据能在线程范围内使用,我用了 HashMap 来存储不同线程中的数据,key 为当前线程,value 为当前线程中的数据.我取的时候根据 ...
- JAVA中的线程安全与非线程安全
原文:http://blog.csdn.net/xiao__gui/article/details/8934832 ArrayList和Vector有什么区别?HashMap和HashTable有什么 ...
- java 多线程 线程安全及非线程安全的集合对象
一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读取完之后,其他线程才可以使用.防止出现数据不一致或 ...
- Java多线程之非线程安全
在Java多线程中我会重点总结五个如下的技术点: 1.非线程安全是如何出现的 2.synchronized对象监视器为Objec时的使用 3.synchronized对象监视器为Class时的使用 4 ...
- java中线程安全和非线程安全的集合
线程安全 非线程安全 Collection Vector ArrayList.LinkedList HashSet.TreeSet Map HashTable HashMap.TreeMap 字符串 ...
- Java线程安全和非线程安全
ArrayList是非线程安全的,Vector是线程安全的:HashMap是非线程安全的,HashTable是线程安全的:StringBuilder是非线程安全的,StringBuffer是线程安全的 ...
- 为什么JAVA虚拟机分为线程共享和非线程共享?
大多数 JVM 将内存区域划分为 Method Area(Non-Heap)(方法区) ,Heap(堆) , Program Counter Register(程序计数器) , VM Stack(虚拟 ...
随机推荐
- 遍历输出tuple元素的简洁方式(C++11)
//遍历输出tuple元素的简洁方式(C++11) //Win32Con17_VS2017_01.cpp #include <iostream> #include <tuple> ...
- jQuery使用serialize(),serializeArray()方法取得表单数据+字符串和对象类型两种表单提交的方法
原始form表单值获取方式(手动): $.ajax({ type: "POST", url: "ajax.php", data: "Name=摘取天上 ...
- EventBus在Android中的简单使用
EventBus是一个方便与Android中各组件通信的开源框架,开源地址;https://github.com/greenrobot/EventBus.EventBus功能非常强大 ,今天在做一个功 ...
- HDOJ 4251 The Famous ICPC Team Again
划分树水题..... The Famous ICPC Team Again Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 3276 ...
- hdu5418--Victor and World(floyd+状压dp)
题目链接:点击打开链接 题目大意:有n个城市.在n个城市之间有m条双向路.每条路有一个距离.如今问从1号城市去游览其他的2到n号城市最后回到1号城市的最短路径(保证1能够直接或间接到达2到n).(n& ...
- Docker 搭建 etcd 集群
阅读目录: 主机安装 集群搭建 API 操作 API 说明和 etcdctl 命令说明 etcd 是 CoreOS 团队发起的一个开源项目(Go 语言,其实很多这类项目都是 Go 语言实现的,只能说很 ...
- 后台返回json可能会出现的异常解析:java.lang.IllegalStateException: WRITER
在使用filter做权限管理限制访问时,经常是在数据可以正确返回时,在后台日志中却有这个异常抛出,这个现象让人不禁想去一探究竟. 我要做的是在一个filter中拦截所有的请求,并且根据拿到的请求中的参 ...
- Spring Boot实战之逐行释义HelloWorld
一.前言 研究Spring boot也有一小段时间了,最近会将研究东西整理一下给大家分享,大概会有10~20篇左右的博客,整个系列会以一个简单的博客系统作为基础,因为光讲理论很多东西不是特别容易理解 ...
- mybatis 基础
前言 MyBatis作为一款持久层的框架,从最初的ibatis更名,经过五六年的发展更新,如今已经更新到了3.4.5版本.MyBatis通过简单的xml或注解配置,就能将接口和Java的对象映射成数据 ...
- 关于Sublime Text编辑器的实用技巧
本文转载至一篇博文,为您提供Sublime Text编辑器的12个技巧和诀窍,深入挖掘这个看似简洁的代码编辑器,背后所隐藏的实现各种高级功能的无限可能. 1) 选择 以下是一些Sublime Text ...