关于hashmap 与concurrentHashMap
hashmap是不安全的,要实现安全,可以用Collections里面的synchronizedMap包裹来实现安全,或者用concurrentMap,
注意:hashtable是安全的
从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心。
在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从此Map也有安全的了。
ConcurrentHashMap具体是怎么实现线程安全的呢,肯定不可能是每个方法加synchronized,那样就变成了HashTable。
从ConcurrentHashMap代码中可以看出,它引入了一个“分段锁”的概念,具体可以理解为把一个大的Map拆分成N个小的HashTable,根据key.hashCode()来决定把key放到哪个HashTable中。
在ConcurrentHashMap中,就是把Map分成了N个Segment,put和get的时候,都是现根据key.hashCode()算出放到哪个Segment中:
测试程序:
- import java.util.concurrent.ConcurrentHashMap;
- public class ConcurrentHashMapTest {
- private static ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<Integer, Integer>();
- public static void main(String[] args) {
- new Thread("Thread1"){
- @Override
- public void run() {
- map.put(3, 33);
- }
- };
- new Thread("Thread2"){
- @Override
- public void run() {
- map.put(4, 44);
- }
- };
- new Thread("Thread3"){
- @Override
- public void run() {
- map.put(7, 77);
- }
- };
- System.out.println(map);
- }
- }
ConcurrentHashMap中默认是把segments初始化为长度为16的数组。
根据ConcurrentHashMap.segmentFor的算法,3、4对应的Segment都是segments[1],7对应的Segment是segments[12]。
(1)Thread1和Thread2先后进入Segment.put方法时,Thread1会首先获取到锁,可以进入,而Thread2则会阻塞在锁上:
(2)切换到Thread3,也走到Segment.put方法,因为7所存储的Segment和3、4不同,因此,不会阻塞在lock():
以上就是ConcurrentHashMap的工作机制,通过把整个Map分为N个Segment(类似HashTable),可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。
关于hashmap 与concurrentHashMap的更多相关文章
- [Java集合] 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.
注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享. 原文地址: http://blog.csdn.net/zhanger ...
- HashMap和ConcurrentHashMap流程图
本文表达HashMap和ConcurrentHashMap中的put()方法的执行流程图,基于JDK1.8的源码执行过程. HashMap的put()方法: ConcurrentHashMap的put ...
- HashMap与ConcurrentHashMap的测试报告
日期:2008-9-10 测试平台: CPU:Intel Pentium(R) 4 CPU 3.06G 内存:4G 操作系统:window server 2003 一.HashMap与Concurre ...
- 轻松理解 Java HashMap 和 ConcurrentHashMap
前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常用于在内存中存放数据. 本篇主要想讨论 ConcurrentHashMap 这样一个并发容器,在正式开始之前我觉得有必要谈谈 ...
- Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析
Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析 今天发一篇”水文”,可能很多读者都会表示不理解,不过我想把它作为并发序列文章中不可缺少的一块来介绍.本来以为花不了 ...
- Java中关于Map的使用(HashMap、ConcurrentHashMap)
在日常开发中Map可能是Java集合框架中最常用的一个类了,当我们常规使用HashMap时可能会经常看到以下这种代码: Map<Integer, String> hashMap = new ...
- Java7/8 中 HashMap 和 ConcurrentHashMap的对比和分析
大家可能平时用HashMap比较多,相对于ConcurrentHashMap 来说并不是很熟悉.ConcurrentHashMap 是 JDK 1.5 添加的新集合,用来保证线程安全性,提升 Map ...
- 高并发第九弹:逃不掉的Map --> HashMap,TreeMap,ConcurrentHashMap
平时大家都会经常使用到 Map,面试的时候又经常会遇到问Map的,其中主要就是 ConcurrentHashMap,在说ConcurrentHashMap.我们还是先看一下, 其他两个基础的 Map ...
- 深入理解HashMap和concurrentHashMap
原文链接:https://segmentfault.com/a/1190000015726870 前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常用于在内存中存放数据. 本篇 ...
- 沉淀再出发:java中的HashMap、ConcurrentHashMap和Hashtable的认识
沉淀再出发:java中的HashMap.ConcurrentHashMap和Hashtable的认识 一.前言 很多知识在学习或者使用了之后总是会忘记的,但是如果把这些只是背后的原理理解了,并且记忆下 ...
随机推荐
- shell脚本学习总结03--别名的使用
1.创建别名 $ alias dms='cd Oracle/Middleware/user_projects/domains/7001_costctl/' $ dms $ dms $ pwd /hom ...
- shell脚本学习总结01--文件描述符和重定向
文件描述符是与文件输入和输出的相关联的整数,它们用来追踪已打开的文件,文件描述符0,1,2是系统预留的. 0 --> stdin (标准输入) 1 --> stdout (标准输出) 2 ...
- shell脚本学习总结11--脚本调试
参数: -n 不执行脚本,仅检查语法是否错误 -v 将脚本内容输出到屏幕上,然后执行脚本 -x 执行脚本,并将内容输出到屏幕 -n [root@new sbin]# sh -n deb ...
- 常问面试题:C++中sizeof的陷阱及应答
C++中sizeof是经常被问到的一个概念,比如,下面的几个关于sizeof的面试题反复出现在各大IT公司的技术面试当中,我们有必要完全理解并掌握.注:在曾经面试大公司时,我的确被问到过这样的问题. ...
- 【BZOJ2956】模积和 分块
[BZOJ2956]模积和 Description 求∑∑((n mod i)*(m mod j))其中1<=i<=n,1<=j<=m,i≠j. Input 第一行两个数n,m ...
- Tips-Windows 10【多桌面视窗】操作
Windows 10[多桌面视窗] 当你点击任务栏上的“task view”按键时,会在屏幕中间显示你当前正在使用的桌面,你可以点击“添加桌面”来创建一个新的桌面,在这个新的桌面你可以打开其他的应用程 ...
- kibana5.6 源码分析以--环境搭建&技术准备
Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的.你可以用kibana搜索.查看.交互存放在Elasticsearch索引里的数据,使用各种不同的图表.表格 ...
- WHICH ONE IS BETTER FOR NEWBIE?
DROP PROCEDURE IF EXISTS w_array; DELIMITER /w/ )) BEGIN ) DO SET @w = LOCATE(',', w_arr); ); SET @w ...
- java基础02
使用 myeclipse写第一个java程序 之后 右键 点击 src 创建 Class /** * package:包的声明! * 代表我们当前的java源文件在项目中的位置! * 必须位于除了 ...
- 【react读取文件】react发送GET请求读取静态文件
react中,使用发送请求的方式把static文件夹中的前端可访问的静态文件读取成字符串: 1.new request,需要用到getRequestHeaders组件 2.fetch获取respons ...