HashMap与ConcurrentHashMap的区别(转)
从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的区别(转)的更多相关文章
- 一、基础篇--1.2Java集合-HashMap和ConcurrentHashMap的区别【转】
http://www.importnew.com/28263.html 今天发一篇”水文”,可能很多读者都会表示不理解,不过我想把它作为并发序列文章中不可缺少的一块来介绍.本来以为花不了多少时间的,不 ...
- HashMap与ConcurrentHashMap的区别
从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...
- java基础知识再学习--HashMap与ConcurrentHashMap的区别
引用:http://blog.csdn.net/xuefeng0707/article/details/40834595 从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是 ...
- HashTable、HashMap、ConcurrentHashMap的区别
HashTable是做了同步的,HashMap未考虑同步.所以HashMap在单线程情况下效率较高:HashTable在的多线程情况下,同步操作能保证程序执行的正确性. HashMap是非线程安全的, ...
- HashMap,HashTable,concurrentHashMap,LinkedHashMap 区别
HashMap 不是线程安全的 HashTable,concurrentHashMap 是线程安全 HashTable 底层是所有方法都加有锁(synchronized) 所以操作起来效率会低 con ...
- HashMap与ConcurrentHashMap的区别<转>
从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...
- HashMap与ConcurrentHashMap的区别(转)
从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...
- 面试题:HashMap和ConcurrentHashMap的区别,HashMap的底层源码。
Hashmap本质是数组加链表.根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面. ConcurrentHashMap:在hashMap的基 ...
- HashMap和ConcurrentHashMap的区别,HashMap的底层源码。
Hashmap本质是数组加链表.根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面. ConcurrentHashMap:在hashMap的基 ...
随机推荐
- jQuery的width()、innerWidth()、outerWidth()方法
width(): 不包括元素的外边距(margin).内边距(padding).边框(border)等部分的宽度. innerWidth(): 包括元素的内边距(padding),但不包括外边距(ma ...
- I-O流概念认知升级
在文件操作基础入门中,我们提到了流的 概念,这篇我们将更多的介绍流这个东西,以及C的I/O相关知识 现在,我们从C程序员最熟悉的printf函数开始学习I/O流. 我们对printf函数一直是很喜爱的 ...
- everything 全盘文件查找工具及正则表达式的使用
首先需要开启 everything 工具在(字符串)查找时,对正则表达式功能的支持: [菜单栏]⇒ [Search]⇒ 勾选[Enable Regex] ctrl + i:字符大小写敏感/不敏感 1. ...
- R 之 rJava 包安装错误的解决方案
前几天在Ubuntu上安装R中的xlsx包时一直卡在了rJava包的安装上,最终各种google都没能解决问题.直到最后,我回到了安装rJava时的错误记录....我用血的教训证明,错误日志是很重要很 ...
- mysql 视图,触发器,存储
一.视图 概念:其实就是一个临时表. 视图是一个虚拟表(非真实存在的),其本质是[根据SQL语句获取动态的数据库,并为其命名],用户使用时只需使用[名称]即可获取结果集.就可以当做表来使用. # 1. ...
- 在JVM中,新生代和旧生代有何区别?GC的回收方式有几种?server和client有和区别?
在JVM中,新生代和旧生代有何区别?GC的回收方式有几种?server和client有和区别? 2014-04-12 12:09 7226人阅读 评论(0) 收藏 举报 分类: J2SE(5) 一 ...
- Android中Activity的LauchMode(加载模式)
1.standard模式:一个task有多个Activity,一个Activity可以被实例化多次,可以放在不同的task中. 2.singleTop模式:该Activity在栈顶,同时收到启动该Ac ...
- 给UIButton设置阴影及动画组
//设置“开启旅程”按钮 UIButton *startBtn = self.startBtn; CGFloat btnW = ; CGFloat btnH = ; CGFloat btnX = (s ...
- 洛谷P1119 灾后重建
传送门 题目大意:点被破坏,t[i]为第i个点修好的时间,且t[1]<t[2]<t[3].. 若干询问,按时间排序,询问第t时刻,u,v的最短路径长度. 题解:floyed 根据时间加入点 ...
- C# 实现程序只启动一次(多次运行激活第一个实例,使其获得焦点,并在最前端显示)
防止程序运行多个实例的方法有多种,如:通过使用互斥量和进程名等.而我想要实现的是:在程序运行多个实例时激活的是第一个实例,使其获得焦点,并在前端显示. 主要用到两个API 函数: ShowWindow ...