在酷壳上看到博主陈皓写的最新文章疫苗:Java HashMap的死循环。博主看问题非常透彻,代码分析到位,而且图文并茂,很容易让人理解一个死循环是怎么产生的。

在博文中,耗子叔叔分析的最重要的一点就是HashMap在ReHash的这个过程中,由于多线程操作容器,意外地很隐蔽地构造了一个环形链接导致了死循环(Infinite Loop)。

给我的启示简单总结如下:

一、单线程改造为多线程也是个技术活

正如我们看到耗子叔叔博客里写的那样,原来是单线程的应用程序,”后来,我们的程序性能有问题,所以需要变成多线程的,于是,变成多线程后到了线上,发现程序经常占了100%的CPU“。

考虑到是淘宝的工程师曝出来的问题,他们的技术基础一般都很扎实,连他们都用错了,所以把单线程改造为多线程并不是想象中的那么简单,我认为。

你可能很不服气地反问,淘宝的工程师又怎么了,单线程改为多线程有什么难的?无非就是应用现有的多线程技术嘛,你看,我有非常强烈的线程安全意识,我知道同步、死锁、竞态条件,还知道lock free和线程安全容器,还知道各种线程安全同步构造……难道还写不出线程安全的应用程序?

实际情况是,线程安全的应用程序并不一定因为你有扎实的线程安全基础和开发经验就能够写好的。

试着举两个例子:

1、使用线程安全容器通过索引取数据

很多人知道的线程安全容器,实际使用的时候并不一定不出现BUG,下面的(有隐患的)代码就比较典型:

        static int GetFirstOrDefault(ThreadSafeList<int> list){if (list.Count > 0){return list[0];}return 0;}

上面的函数参数list如果一开始传入一个元素总数为1的列表,大家能分析出上面的代码会有什么问题吗?

关于线程安全容器,之前我恰好也总结过一篇文章浅析线程安全容器的实现。线程安全容器并不真正安全,上面有问题的代码就是出自于这里。

2、多线程操作邮件的失误

还有就是多线程应用场景的分析可能不正确,曾经因为一个邮件收发程序的性能问题,我也大胆改造过应用程序,改来改去就出现了重大BUG,

大家可以看看我痛心疾首总结过的一个应用程序多线程误用的分析。

上面举的这两个例子,我只是想说明,多线程应用程序中,因为线程安全产生的BUG其实是很微妙的,一个考虑不周或者认识不够深刻,出现问题的可能性简直防不胜防。

二、ReHash的代价

上面第一点主要是闲谈线程安全,接着我们也说说哈希表,深刻理解消耗成本很大的ReHash。

我们平常理解中的哈希表是“以空间换时间的一种数据结构”。这样说的太久了,大家可能会有一种直观上的错觉,就是哈希表牺牲的是空间,争取的是时间。

但是,ReHash的过程其实是空间和时间的双重重大损失,因为分析源代码,我们知道ReHash的过程其实就是一个动态扩容的过程,而哈希表的扩容是个空间和时间消耗都非常惊人的内部操作。

为什么说ReHash是个空间和时间消耗都非常惊人的内部操作呢?

1、原来当我们对哈希结构的容器进行扩容时,散列表内部要重新new一个更大的数组,然后把原来数组的内容拷贝到新数组,并进行重新散列;

2、new出来的这个更大的新数组容量有多大也是一门学问,一般来说,新数组的大小会设置成原数组双倍大小的相近的一个素数(.NET中这个素数的生成还有一定的技巧)。

从1和2这两点可以看出,ReHash的代价确实非常高。在不久以前我碰巧写过一篇关于.NET容器的动态扩容的文章(从源码分析常见的基于Array的数据结构动态扩容机制),其中也浅显总结了.NET的HashTable的扩容机制,现在对照Java中的HashMap源码,看到熟悉的ReHash函数命名,再看一遍.NET中的实现,果然有比较才能有提高。

至于我们平时所理解的“以空间换时间“,其实是指哈希具有O(1)复杂度的数据检索效率,但它受填充因子影响,空间开销通常很大,空间利用率不高。

所以我们常常说哈希表适用于读操作频繁,写操作较少应用场景,比如把哈希表当做缓存容器,于我心有戚戚焉。

最后看到这句“有人把这个问题报给了Sun,不过Sun不认为这个是一个问题。因为HashMap本来就不支持并发。要并发就用ConcurrentHashmap…”

根据实际开发经验,线程安全的容器并不真正线程安全,会用ConcurrentHashmap也只是进入初级阶段,同时忍不住要感慨下当年如日中天风光无限的Sun。

本文转自JeffWong博客园博客,原文链接:http://www.cnblogs.com/jeffwongishandsome/archive/2013/05/12/3073023.html,如需转载请自行联系原作者

Java HashMap的死循环的启示相关推荐

  1. Java HashMap的死循环问题

    看到过很多CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环.这个事情我4.5年前也经历过,本来觉得 ...

  2. 疫苗:Java HashMap的死循环(转)

    在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环.这个事情我4. ...

  3. 疫苗:JAVA HASHMAP的死循环

    转至:https://coolshel 在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condi ...

  4. Java HashMap的死循环

    http://coolshell.cn/articles/9606.html 问题的症状 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题.后来 ...

  5. Java HashMap的工作原理 及各种Map区别

    2019独角兽企业重金招聘Python工程师标准>>> 一.Java HashMap的工作原理 jdk1.7下HashMap数据结构:数组加链表,链表长度没有8的限制: jdk1.8 ...

  6. LeetCode(13.罗马数字转整数) JAVA Hashmap

    LeetCode(13.罗马数字转整数) JAVA Hashmap 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D ...

  7. java HashMap的使用

    java HashMap的使用 import java.util.HashMap; import java.util.Iterator; public class WpsklHashMap { pub ...

  8. Java HashMap工作原理深入探讨

    大部分Java开发者都在使用Map,特别是HashMap.HashMap是一种简单但强大的方式去存储和获取数据.但有多少开发者知道 HashMap内部如何工作呢?几天前,我阅读了java.util.H ...

  9. java hashmap 去重复_为什么我在Java HashMap中得到重复的键?

    本问题已经有最佳答案,请猛点这里访问. 我似乎在标准Java HashMap中得到重复的键."重复"是指键的equals()方法相等.这是有问题的代码: import java.u ...

最新文章

  1. Spark Streaming实时计算框架介绍
  2. hive json 获取_hive sql 解析json
  3. “哎哟,真的很快哦” 闪送宣布签约周杰伦为其品牌代言人
  4. 文字加减前后缀lisp_日本搞笑艺人催泪讲授汉字课堂告诉你文字背后的意义!...
  5. 两个list取交集_Java基础面试题-说说你知道的几个Java集合类:list、set、queue、map...
  6. Java 多线程(一)并发、并行、线程、多线程、进程
  7. 传智播客 机器学习之数据降维 学习笔记
  8. 知云文献翻译出现乱码的解决方式
  9. 分享一些使用电脑的小技巧
  10. 浅谈C#tabcontrol应用
  11. 高中分班考试如何计算机,新高一生如何应对分班考?
  12. 哈尔滨工业大学计算机考研难吗,哈尔滨工业大学计算机考研经验:只有意志坚强才能到达彼岸...
  13. 显示器知识:分辨率1080P、2K、4K、8K相关知识介绍,看完你就懂了!
  14. 2020最新as项目中添加jni---------静态注册
  15. 《平凡的世界》(书评)
  16. 卡塞格林光学系统_卡塞格林红外光学系统装调技术研究
  17. Ubuntu在线安装NFS服务
  18. 表单注册表单注册表单注册
  19. python识别电脑图像_计算机屏幕图像识别
  20. 案例分享 | TensorFlow 在贝壳找房中的实践

热门文章

  1. Spring MVC-08循序渐进之国际化(基于Session-SessionLocaleResolver)
  2. 60进制计算器在线_超长假期用华为MatePad Pro在线听课是怎样的体验?
  3. oracle原始数据类型,Oracle基本数据类型存储格式浅析——RAW类型
  4. Docker安装配置Nginx
  5. docker 安装svn
  6. 如何用pip指令将python包安装到虚拟环境中
  7. Halcon初学者知识【15】图像的定义域Domain
  8. matlab编程选择语句,matlab编程控制语句
  9. Matlab实用程序--图形应用-条形图和阶梯形图
  10. 人工神经网络理论、设计及应用_TensorFlow深度学习应用实践:教你如何掌握深度学习模型及应用...