`
HWL_SZ
  • 浏览: 54276 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

HashMap死锁原因及替代方案

 
阅读更多

1、首先我们需要简单地了解一下HashMap数据结构
HashMap通常会用一个指针数组(假设为table[])来做分散所有的key,当一个key被加入时,会通过Hash算
法通过key算出这个数组的下标i,然后就把这个<key, value>插到table[i]中,如果有两个不同的key被算了。
但有时候两个key算出的下标会是一个i,那么就叫冲突,又叫碰撞,这样会在table[i]上形成一个链表。所以
如果链表过多或过长,查找算法则会变成低性能的链表遍历,这是Hash表的缺陷。


我们都知道HashMap初始容量大小为16,一般来说,Hash表这个容器当有数据要插入时,都会检查容量有没有超过设定的thredhold,如果超过,需要增大Hash表的尺寸,但是这样一来,整个Hash表里的元素都需要被重算一遍。这叫rehash,这个成本相当的大。具体大家可以看看JDK源码


2、现在来讨论死锁产生的原因
HashMap是非线程安全,死锁一般都是产生于并发情况下。我们假设有二个进程T1、T2,HashMap容量为2,T1线程放入key A、B、C、D、E。在T1线程中A、B、C Hash值相同,于是形成一个链接,假设为A->C->B,而D、E Hash值不同,于是容量不足,需要新建一个更大尺寸的hash表,然后把数据从老的Hash表中
迁移到新的Hash表中(refresh)。这时T2进程闯进来了,T1暂时挂起,T2进程也准备放入新的key,这时也
发现容量不足,也refresh一把。refresh之后原来的链表结构假设为C->A,之后T1进程继续执行,链接结构
为A->C,这时就形成A.next=B,B.next=A的环形链表。一旦取值进入这个环形链表就会陷入死循环。

 

3、替代方案
使用ConcurrentHashMap进行替代,ConcurrentHashMap是一个线程安全的Hash Table。可能有人会使用HashTable。当然HashTable也是线程安全,但HashTable锁定的是整个Hash表,效率相对比较低。而ConcurrentHashMap可以做到读取数据不加锁,并且其内部的结构可以让其在进行写操作的时候能够将锁的粒度保持地尽量地小,

1
1
分享到:
评论
2 楼 steafler 2014-01-27  
java中只有线程的概念
1 楼 snipertarget 2013-07-02  
HashMap本身并没有错,错的是使用它的人把它用错了地方。说它造成死锁,造成cpu100%,只能说使用者没不太清楚应用场景.工具只是工具,如果程序出了问题,归根还是人的问题。

相关推荐

    java的hashMap多线程并发情况下扩容产生的死锁问题解决.docx

    如果你在多线程环境中使用HashMap并遇到死锁问题,有以下几种解决方案: 1. 使用ConcurrentHashMap替代HashMap,以保证线程安全。 2. 在多线程操作HashMap时,使用适当的同步机制,如synchronized关键字或Lock对象,...

    【java系列文章】java 基础知识

    永久代是JVM早期版本中存储类元数据的地方,但在Java 8及之后版本,这部分被元空间(Metaspace)替代。 8. Dubbo与Spring Cloud的区别: - Dubbo是一个高性能、轻量级的Java RPC框架,专注于服务治理,如服务注册...

    C#、.Net经典面试题目及答案.doc

    BS结构中变量传递的替代方案 除了`session`、`cookie`、`application`之外,可以使用`Request.QueryString`或服务器端转移(`Server.Transfer`)等技术在Web应用程序中传递数据。 ### 14. 索引器的实现与使用 索引...

    JAVA并发编程实践高清版带书签PDF

    4. **锁与同步替代方案**:除了synchronized,书中还介绍了Lock接口及其实现,如ReentrantLock,以及读写锁(ReadWriteLock),这些提供了更细粒度的控制和更高的并发性能。 5. **并发集合**:书中详细讲解了并发...

    JAVA面试很全的一个资料,不过仅针对面试哦,日常学习不合适。内容以问答形式。

    方法区主要存储类的静态变量、常量和元数据,随着JVM的演进,这部分在Java 8后被元空间替代,元空间使用本地内存,避免了内存溢出问题。 Java集合框架是面试中的常见话题,包括ArrayList、LinkedList、HashSet、...

    JAVA程序设计教程

    同时,接口(Interface)在Java中的重要地位也会被提及,它是实现多继承的替代方案。 异常处理是Java程序设计中的重要环节,教程会介绍如何使用try-catch块来捕获和处理程序运行时可能出现的错误,以提高程序的健壮...

    经典面试题目33条C#

    - **替代方案**: - 使用`Server.Transfer`方法跳转页面。 - 使用查询字符串`QueryString`传递参数。 #### 15. 索引器 - **定义**:索引器允许对象像数组一样使用下标来访问元素。 - **实现过程**:通过`this...

    Java Bug模式详解 pdf版

    9. **线程不安全的类**:书中会列举一些线程不安全的类,如SimpleDateFormat,并提供替代方案,如使用java.time包中的类。 10. **设计模式与重构**:最后,书中可能会提到一些设计模式,如单例模式、工厂模式,以及...

    JAVA高质量并发详解,多线程并发深入讲解

    分析导致死锁的常见原因,以及如何通过合理的设计和编码来预防死锁的发生。 - **第30章:非阻塞同步机制** 介绍非阻塞同步的基本概念,包括悲观锁和乐观锁的区别,以及比较并交换(CAS)机制的工作原理。 - **第31...

    Java实用程序设计100例

    - **JavaFX简介**:了解JavaFX作为现代Java GUI开发的替代方案。 - ** scenegraph与控件**:构建场景图,使用JavaFX控件创建复杂UI。 通过研究这些实例,读者不仅能学习到Java语言的基础语法,还能深入了解Java的...

    java基础课程教学ppt

    接口则是一种完全抽象的类型,只包含常量和抽象方法,是多继承的替代方案。 9. **异常处理**:Java提供了异常处理机制,通过try-catch-finally语句块来捕获和处理程序运行时可能出现的错误,保证程序的健壮性。 10...

    java面试题-经典选择题部分

    面试中可能会考察如何编写高效的代码,例如使用三元运算符替代if语句。 2. **面向对象**:Java是面向对象的语言,面试时会关注封装、继承、多态等概念。可能会问及访问修饰符的区别,抽象类与接口的比较,以及重写...

    java课件-讲的很不错

    接口作为抽象类的一种替代方案,允许类实现多个接口,以实现多重继承的效果。接口在Java中扮演着重要的角色,特别是在设计大型软件系统时。 【第5章 常用系统类】 在这一章中,我们将接触到Java标准库中的常用类,...

    java 基础篇 课后答案

    它是多继承的替代方案,用于定义行为规范。 - 抽象类可以包含抽象方法和非抽象方法,作为类的一个基类,提供部分实现。 9. **包与导入** - 包是组织Java类的一种方式,通过import关键字可以引入其他包中的类,...

    java基础面试题

    Servlet是Java Web开发中处理客户端请求的核心技术之一,它提供了一种更高效、更可扩展的替代方案来代替传统的CGI(Common Gateway Interface)。Servlet在被初始化后会驻留在内存中,这使得它们能够更快地响应后续...

    Java经典问题答案(带书签).pdf

    - 同步问题也可能由于不正确的锁对象选择等原因造成。 **线程的优先级** - 线程的优先级通过`setPriority()`方法设置。 - 优先级高的线程更有可能被调度执行。 **线程获取名称** - 线程名称通过`Thread.setName...

    Hetgames-sollicitatie:我的文件中只有几个文件,它们是Java脚本

    非阻塞I/O(New IO, NIO)是Java提供的一种替代方案,用于提高大规模数据处理的效率。 5. **多线程**:Java内置对多线程的支持,允许同时执行多个任务。Thread类和Runnable接口是实现多线程的两种主要方式,理解...

    randomJava:一些随机 Java 代码

    5. 集合框架:Java提供了强大的集合框架,如ArrayList、LinkedList、HashSet、HashMap等,用于存储和操作数据。了解它们的区别、性能特征以及如何使用迭代器是Java编程的基础。 6. 文件与I/O流:Java提供了丰富的类...

Global site tag (gtag.js) - Google Analytics