HashMap之原理及死锁
一、HashMap原理
1.HashMap的本质就是数组和链表。table是一个entry数组,每一个数组元素保存一个Entry节点,而Entry节点内部又连接着同样key的下一个Entry节点,就构成了链表。.
详情见 HashMap源码分析
2.HashMap死锁原因:
HashMap会造成死锁,因为HashMap是线程非安全的,多并发的情况容易造成死锁,若要高并发推荐使用ConcurrentHashMap。这里的加了锁。
高并发时引起HashMap死锁的原因分析:
HashMap死锁原因分析
总的来说是:
Hash表的初始大小(HashMap初始容量大小为16)有限,当put存入的数据增加时就必须扩容了,源码中会调用rehash方法(即是把原表内容移入到一个新的表中),单线程下rehash就是把原来链表遍历,从新的链表头部(为什么不加到新链表最后?因为复杂度是
O(N))挨个放入,放入的过程中依次执行函数transfer();
Entry<K,V> next = e.next;//保留头指针的下一个节点——因为是单链表,如果要转移头指针,一定要保存下一个结点,不然转移后链表就丢了
e.next = newTable[i];//插入到链表的头部——e 要插入到链表的头部,所以要先用 e.next 指向新的 Hash 表第一个元素(为什么不加到新链表最后?因为复杂度是 O(N))
newTable[i] = e;//——现在新 Hash 表的头指针仍然指向 e 没转移前的第一个元素,所以需要将新 Hash 表的头指针指向 e
e = next//——转移 e 的下一个结点
- 1
- 2
- 3
- 4
- 5
- 6
多线程的时候会出现同时
put()操作,并进入了transfer()环节;
假设现在有三个线程:T1,T2,T3;在老数组中的第一个数据也就是e引用的对象,我们称它为A,在新数组中的头两个数据分别为B和C,B.next=C。
线程T1运行到e.next=newTable[i]时线程T2运行到next=e.next;然后线程t1去继续;
运行,会产生什么效果呢?A.next=B,B.next=C。e指向的对象是B,newTable[i]=A。然后继续运行,e.next=newTable[i],也就是B.next=A;同时A.next=B,继续运行newTable[i]
= e,e = next;如果没有其它线程捣乱的话,那么此时e应该是C啊,可惜只是如果,如果有第三个线程T3在线程T1执行e.next =
newTable[i]的时候去执行next =
e.next;那么就中途改变了next的值,本来是保存C的,但是现在成了A了。总结下现在的情况:e引用A,nextTable[i]引用B,A.next=B,B.next=A。现在明白了吧。会一直这么死锁下去的。
HashMap之原理及死锁的更多相关文章
- 【JAVA】HashMap的原理及多线程下死循环的原因
再次翻到以前工作中遇到的一个问题,HashMap在多线程下会出现死循环的问题,以前只是知道会死循环,导致CPU100%把机器拖跨,今天来彻底看看 首先来看下,HashMap的原理:HashMap是一个 ...
- 最简单的HashMap底层原理介绍
HashMap 底层原理 1.HashMap底层概述 2.JDK1.7实现方式 3.JDK1.8实现方式 4.关键名词 5.相关问题 1.HashMap底层概述 在JDK1.7中HashMap采用的 ...
- HashMap实现原理及源码分析
哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...
- 【JDK源码分析】浅谈HashMap的原理
这篇文章给出了这样的一道面试题: 在 HashMap 中存放的一系列键值对,其中键为某个我们自定义的类型.放入 HashMap 后,我们在外部把某一个 key 的属性进行更改,然后我们再用这个 key ...
- HashMap的原理与实 无锁队列的实现Java HashMap的死循环 red black tree
http://www.cnblogs.com/fornever/archive/2011/12/02/2270692.html https://zh.wikipedia.org/wiki/%E7%BA ...
- JVM里面hashtable和hashmap实现原理
JVM里面hashtable和hashmap实现原理 文章分类:Java编程 转载 在hashtable和hashmap是java里面常见的容器类, 是Java.uitl包下面的类, 那么Hash ...
- 基础进阶(一)之HashMap实现原理分析
HashMap实现原理分析 1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二 ...
- Java HashMap工作原理及实现
Java HashMap工作原理及实现 2016/03/20 | 分类: 基础技术 | 0 条评论 | 标签: HASHMAP 分享到:3 原文出处: Yikun 1. 概述 从本文你可以学习到: 什 ...
- HashMap实现原理和源码解析
哈希表(hash table)也叫散列表,是一种非常重要的数据结构.许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,本文会对java集合框架中的对应实现HashMap的 ...
随机推荐
- 【树链剖分】【线段树】bzoj3083 遥远的国度
记最开始的根为root,换根之后,对于当前的根rtnow和询问子树U而言, ①rtnow==U,询问整棵树 ②fa[rtnow]==U,询问除了rtnow所在子树以外的整棵树 ③rtnow在U的子树里 ...
- 【字符串哈希】bzoj3098 Hash Killer II
教育我们做Rabin-Karp的时候一定要把模数取大?还是上溢好了. #include<cstdio> #include<cstdlib> using namespace st ...
- 金融应用,计算未来投资回报值 Exercise06_07
import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年下半年 * 题目:金融应用,计算未来投资回报值 * */ public class Exer ...
- Missing iOS Distribution signing identity解决方案
相信很多朋友跟我遇到相同的问题,之前iOS发布打包的证书没问题,现在莫名其妙的总是打包失败,并且报如下错误 第一反应,是不是证书被别人搞乱了.于是去Developer Member Center,把所 ...
- 使用Python的turtle模块画出最简单的五角星
代码如下: import turtle def main(): t = turtle.Turtle() t.hideturtle() lengthOfSize = 200 drawFivePointS ...
- NHibernate+MySql (erro 解决方法)
error1. Could not create the driver from NHibernate.Driver.MySqlDataDriver 解决方法:在使用Nhibernate连接Mysq ...
- Linux Hook 笔记
相信很多人对"Hook"都不会陌生,其中文翻译为"钩子".在编程中, 钩子表示一个可以允许编程者插入自定义程序的地方,通常是打包好的程序中提供的接口. 比如,我 ...
- puppeteer 相关知识
page.waitForNavigation: 但我们通过代码执行到页面跳转时,我们需要等待跳转完成再作其他事情.使用page.waitForNavigation会等待跳转完成.(一般作用在点击链接或 ...
- 微信小程序 的文字复制功能如何实现?
text设置属性 selectable="true" 就可以长按复制了 文章来源:刘俊涛的博客 地址:http://www.cnblogs.com/lovebing 欢迎关注,有 ...
- wampServer(windows、apache、mysql、php)
wampServer(windows/apche/mysql/php)集成环境 在线状态:区域网内可以访问 离线状态:本地设备可以访问 自拟定网站根目录: Apache -- httpd.conf - ...