好久没写过技术性文章了,还是要坚持下去。掌握的知识,能写出来或者是讲给别人听才是真正的掌握了知识,如果不善于给别人讲,实际上还是没有真正掌握相关的知识,挑个简单的写吧。

面试的时候经常会被问到hashmap和hashtable的区别。心里就开始鄙视这个面试的人了,不要拿这种基础的问题来为难一个抗战都快胜利的码农,那些个条条框框谁xx记得住。可是,遇到牛逼点的单位要问我hashmap结构、算法、这一系列牵扯到移位、与、或、非、异或2进制16进制这些我也真的答不上来,汗。。。下来恶补一下吧。
这时候,可以跟他喷这些,
Hashtable为什么性能低?
HashMap高并下发会发生什么?
HashMap内部结构是什么?
ConcurrentHashmap为什么可以支持高并发?为什么比hashmap读取效率高?
 
hashtable从java1.0就引入了,早年在深圳写java的时候,项目的全局变量里清一色的hashtable,也不了解为什么,用就行了,反正都是卖几个亿的项目,也轮不到自己操心,有时候还要鄙视一下旁边坐的华为的从c转来做java的哥们,还没我知道多。呵呵,自己就是典型的只了解业务不了解原理的码农,当年要跟着大牛混就好了,无奈,身边都是码农。
随着时间的推移,自己也知道主动去了解一些知识,例如hashmap写入慢,读取快;linkedhashmap是个有序链表读取慢,写入快;treeMap可以帮你自动做好升序排列。全局变量就是拿来读着用的嘛,得!发现用hashmap比hashtable性能好,还鄙视当年做项目时候写全局变量的人,随后,自己动手开发的项目全局变量都用起了hashmap。嗯,用着还挺好,也没发现什么问题,呵呵,都是不值钱的小项目,撑死几十个人的并发量,能有什么问题。
终于有一天,boss开始吐槽,你的程序cpu占用率怎么那么高呢,我不以为然,并发量高么,证明咱们业务量大呀,你应该高兴才对。我的数据都在内存里,速度快着呢,估计是循环和job太多了吧,boss一脸懵逼,似懂非懂,反正跟你说也不懂,出于程序员的本能,我还是检查了一遍日志,不好,日志有错误!
目标直指hashmap全局变量,怎么会这样呢,怎么说也搞了这么多年了,第一反应就是,入坑了,hashmap不是线程安全的,光顾着读取快了,没料到这个全局变量随时会多线程读写,为何会出现cpu占用率高呢,有问题,找谷哥,什么,用度娘,算了吧,除了卖假药的,屁都搜不出来。来看看为何cpu会占用率高,因为HashMap以链表组形式存在,初始数组16位(为何16位,又是一堆移位算法,下一篇文章再写吧),如果长度超过75%,长度增加一倍,多线程操作的时候,恰巧两个线程插入的时候都需要扩容,形成了两个链表,这时候读取,size不一样,报错了。其实这时候报错都是好事,至少不会陷入死循环让cpu死了,有种情况,假如两个线程在读,还有个线程在写,恰巧扩容了,这时候你死都不知道咋死的,直接就是死循环,假如你是双核cpu,cpu占用率就是50%,两个线程恰巧都进入死循环了,得!中奖了。
这该咋办,换成Hashtable吧,这点小坑难不住我,想起原来以前深圳的boss系统,其实每一行核心代码都不是随便写的,其实这个问题很早sun的大爷们都发现了,大爷们认为HashMap不是bug,而是使用场景有要求,单线程读取操作,又快又省空间。
难道我写了半天就为了把hashmap换成hashtable,那也太浪费键盘了,我今天重点说的是ConcurrentHashMap,听名字就很牛气,并发的hashmap。其实早在jdk1.5,大约2010年左右,sun的大爷们就推出了ConcurrentHashMap,线程安全,读写还快。你这不是蒙我呢,线程安全和读写速度肯定是成反比的,怎么可能。看了源码才知道,这是一种以空间换时间的结构,跟分布式缓存结构有点像,创建的时候,内存直接分为了16个segment,每个segment实际上还是存储的哈希表,写入的时候,先找到对应的segment,然后锁这个segment,写完,解锁,汗!就这么简单解决了,锁segment的时候,其他segment还可以继续工作。好像听着挺简单的,其实大爷们的代码看着真的很头疼,到处都是移位、与或非,就拿计算存放位置的代码来看,如何均匀的散列,减少位置碰撞都是有讲究的,还是得感叹你大爷就是你大爷。

为什么要使用ConcurrentHashMap的更多相关文章

  1. Java集合---ConcurrentHashMap原理分析

    集合是编程中最常用的数据结构.而谈到并发,几乎总是离不开集合这类高级数据结构的支持.比如两个线程需要同时访问一个中间临界区(Queue),比如常会用缓存作为外部文件的副本(HashMap).这篇文章主 ...

  2. ConcurrentHashMap

    ConcurrentHashMap是Java5中新增加的一个线程安全的Map集合,可以用来替代HashTable.对于ConcurrentHashMap是如何提高其效率的,可能大多人只是知道它使用了多 ...

  3. ConcurrentHashMap内存泄漏问题

    问题背景 上周,同事写了一段ConcurrentHashMap的测试代码,说往map里放了32个元素就内存溢出了,我大致看了一下他的代码及运行的jvm参数,觉得很奇怪,于是就自己捣鼓了一下.首先上一段 ...

  4. Example of ConcurrentHashMap in Java--转

    原文地址:http://www.concretepage.com/java/example_concurrenthashmap_java On this page we will provide ex ...

  5. Java ConcurrentHashMap Example and Iterator--转

    原文地址:http://www.journaldev.com/122/java-concurrenthashmap-example-iterator#comment-27448 Today we wi ...

  6. 【JUC】JDK1.8源码分析之ConcurrentHashMap(一)

    一.前言 最近几天忙着做点别的东西,今天终于有时间分析源码了,看源码感觉很爽,并且发现ConcurrentHashMap在JDK1.8版本与之前的版本在并发控制上存在很大的差别,很有必要进行认真的分析 ...

  7. ConcurrentHashMap和HashMap的一点区别

    HashMap不是线程安全的,ConcurrentHashMap则在某一个方法的执行上是线程安全的. package testMap; import java.util.HashMap; public ...

  8. 【转】HashMap、TreeMap、Hashtable、HashSet和ConcurrentHashMap区别

    转自:http://blog.csdn.net/paincupid/article/details/47746341 一.HashMap和TreeMap区别 1.HashMap是基于散列表实现的,时间 ...

  9. HashMap与ConcurrentHashMap的区别

    从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...

  10. Java集合——ConcurrentHashMap

    集合是编程中最常用的数据结构.而谈到并发,几乎总是离不开集合这类高级数据结构的支持.比如两个线程需要同时访问一个中间临界区(Queue),比如常会用缓存作为外部文件的副本(HashMap).这篇文章主 ...

随机推荐

  1. [C语言] 关于计算多边形面积的一点问题

    [一道练习题] 面基 时间限制:1000ms   内存限制:65536kb 通过率:107/134 (79.85%)    正确率:107/319 (33.54%) 题目描述 按顺时针或逆时针顺序输入 ...

  2. 你应该掌握linux中Bash命令的一些快捷方式

    在本文中,我们将分享许多对任何Linux用户都有用的Bash命令行快捷方式.这些快捷方式可以快速地执行某些动作,例如访问和运行先前执行的命令,打开编辑器,在命令行上编辑/删除/更改文本,移动光标,控制 ...

  3. Pair(二进制处理+数位dp)(2019牛客暑期多校训练营(第七场))

    示例: 输入: 33 4 24 5 27 8 5 输出:5 7 31 题意:存在多少对<x,y>满足x&y>C或x^y<C的条件.(0<x<=A,0< ...

  4. JavaScript Web API 全选反选案例

    全选反选 全选和反选功能,在开发中可以说是应用得非常多的,以下通过案例分解,学习如何使用JS实现全选反选功能. 该功能可分为如下三大步骤: 1.全选 1.1 获取父checkbox,注册点击事件 1. ...

  5. iview 表格随着更改刷新

    使用location.reload() 或者是 路由的 this.$router.go(0) 进行刷新的时候,是会出现一阵的空白区域的,因为是整个页面的刷新 ,所以比较缓慢,因此使用了provide/ ...

  6. 解决 WPF 嵌套的子窗口在改变窗口大小的时候闪烁的问题

    原文:解决 WPF 嵌套的子窗口在改变窗口大小的时候闪烁的问题 因为 Win32 的窗口句柄是可以跨进程传递的,所以可以用来实现跨进程 UI.不过,本文不会谈论跨进程 UI 的具体实现,只会提及其实现 ...

  7. C#判断字符串中包含某个字符的个数

    //定义字符串 var Email= "humakesdkj@idsk@"; //获取@字符出现的次数 int num = Regex.Matches(Email, "@ ...

  8. [winfrom]C#中使用SendMessage

    在C#中,程序采用了的驱动采用了事件驱动而不是原来的消息驱动,虽然.net框架提供的事件已经十分丰富,但是在以前的系统中定义了丰富的消息对系统的编程提供了方便的实现方法,因此在C#中使用消息有时候还是 ...

  9. 和我一起,重零开始学习Ant Design Pro开发解决方案(一)安装开发环境

    安装NODEJS 什么是NODEJS? 百度一下吧,这个真不知道,老码农,别笑话我: 简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于Chrome Jav ...

  10. grep过滤日志

    A -B -C 后面都跟阿拉伯数字 -A是显示匹配后和它后面的n行. -B是显示匹配行和它前面的n行. -C是匹配行和它前后各n行. 总体来说,-C覆盖面最大.用它保险些.哈哈.这3个开关都是关于匹配 ...