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

面试的时候经常会被问到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. R统计数据框的行数

    如下三种方法可以实现 使用dim函数 dim(dataframe)[0] 使用nrow函数 nrow(dataframe) 使用length函数统计 length(dataframe[,1])

  2. javaNIO核心概念

    在java的阻塞IO中使用InputStream和outputStream来进行输入和输出,那么两种流是相互独立使用的,而且每次数据传输都要通过“用户态数据”向“os内核态数据”copy或从“os内核 ...

  3. Springboot采用hibernate-validate验证请求参数

    在springboot项目使用hibernate-validate对请求参数添加注解进行校验 常用注解 @Null,标注的属性值必须为空 @NotNull,标注的属性值不能为空 @AssertTrue ...

  4. Java基础之(四)HashMap(jdk10)

    JDK1.7以前的HashMap jdk1.7中,当冲突时,在冲突的地址上生成一个链表,将冲突的元素的key,通过equals进行比较,相同即覆盖,不同则添加到链表上,此时如果链表过长,效率就会大大降 ...

  5. eoj monthly 2019.11

    原题 T1 纸条 题目大意: 给出一个长度为n的字符串,其中m位未知,对于每一位未知的字母,有k个备选字母,最终答案为备选字母按字典序排序后的第x个. 题解: 签到题-- 按照题目意思直接写就可以了. ...

  6. 【微信小程序学习笔记】入门与了解

    [微信小程序学习笔记(一)] IDE 下载安装 下载地址 官方工具:https://mp.weixin.qq.com/debug/w … tml?t=1476434678461 下载可执行文件后,可按 ...

  7. 为了防止页面重新自动加载,可以给a标签设置href="javascript:void(0);"

    <a href="javascript:void(0);"></a> <!--按照格式要求,此处的0不能省略!! 虽然省略看上去也没什么影响.但是当发 ...

  8. yii2 发送邮件 yii\swiftmailer\Mailer

    Yii2 中发送邮件 yii\swiftmailer\Mailer 'mailer' => [ 'class' => 'yii\swiftmailer\Mailer', 'viewPath ...

  9. Asp.Net进阶/值类型与引用类型:复习

    什么是值类型? 值类型: 就是非类类型,委托类型,接口类型,string类型的类型称为值类型. 引用类型类型:就是类类型,委托类型,接口类型,string类型称为引用类型. 值类型与引用类型的赋值问题 ...

  10. WebApi PUT与DELETE类型访问报错

    * 方法一 在项目的Web.Config文件加入 <modules> <remove name="WebDAVModule" /> </modules ...