通过源码理解HashMap的并发问题
最近在学习有关于Java的基础知识,在学习到HashMap的相关知识的时候,了解了HashMap的并发中会出现的问题,在此记录,加深理解(这篇文章是基于Java1.7的,主要是为了更加直观,更新版本的代码更加复杂,等理解后会继续总结).
HashMap的内部存在一个数组,每个位置存放一个自定义的Node对象,Node对象中存在下一个对象的引用,类似如下结构
每次添加后size属性都会增加,当size属性超过了阈值(表现为大于threshold属性的值)时,会触发resize(itn size)方法,进行扩容,扩容的方式是创建一个2倍大的新的数组,对老transfer()函数,对数组进行遍历重算新hash,并赋值到新数组中,如果程序是并发执行,就容易出现问题.
核心代码如下:
/**
* Transfers all entries from current table to newTable.
*/
void transfer(Entry[] newTable) {
Entry[] src = table;
int newCapacity = newTable.length;
for (int j = 0; j < src.length; j++) {
Entry<K,V> e = src[j];
if (e != null) {
src[j] = null;
do {
Entry<K,V> next = e.next;
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
}
简单来说就是取一个节点,循环找下一个,赋到新的数组中,如果多线程就会出现问题
如果线程a准备扩容,发生线程切换时正好处于这个状态(只是示意图,大小等并不符合真实情况)
此时线程切换,线程b完成了扩容的过程,再切回线程a,此时扩容完成,但是线程a依旧执行,变量仍然指向那些节点,此时如果出现以下情况
此时继续执行,执行了e.next = newTable[i]; newTable[i] = e; e = next;此时就会出现循环列表
此时循环链表出现,当我们调用get()方法,hash在位置,且寻找元素不存在的时候,就会进入死循环无法跳出.
原理的简单描述就是这样,如果需要在并发条件下使用,可以使用Java并发包中的ConcurrentHashMap.
通过源码理解HashMap的并发问题的更多相关文章
- 通过源码理解Spring中@Scheduled的实现原理并且实现调度任务动态装载
前提 最近的新项目和数据同步相关,有定时调度的需求.之前一直有使用过Quartz.XXL-Job.Easy Scheduler等调度框架,后来越发觉得这些框架太重量级了,于是想到了Spring内置的S ...
- 通过源码理解UST(用户栈回溯)
UST原理:如果gflags标志中包含了UST标志,堆管理器会为当前进程分配一块内存,这个内存区域就是UST数据库(user-mode stack trace database),并建立一个STACK ...
- 通过源码了解ASP.NET MVC 几种Filter的执行过程
一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神的工作,而且很多人觉得平时根本不需要知道这些,会用就行了.其实阅读源 ...
- Linux下通过源码编译安装程序
本文简单的记录了下,在linux下如何通过源码安装程序,以及相关的知识.(大神勿喷^_^) 一.程序的组成部分 Linux下程序大都是由以下几部分组成: 二进制文件:也就是可以运行的程序文件 库文件: ...
- 通过源码了解ASP.NET MVC 几种Filter的执行过程 在Winform中菜单动态添加“最近使用文件”
通过源码了解ASP.NET MVC 几种Filter的执行过程 一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神 ...
- 在centos6.7通过源码安装python3.6.7报错“zipimport.ZipImportError: can't decompress data; zlib not available”
在centos6.7通过源码安装python3.6.7报错: zipimport.ZipImportError: can't decompress data; zlib not available 从 ...
- Kafka详解六:Kafka如何通过源码实现监控
问题导读: 1.kafka的消费者组的消费偏移存储,kafka支持两个版本? 2.ConsumerOffsetChecker类的作用是什么? 3.Kafka如何通过源码实现 ...
- 通过源码编译安装VIM
开发中使用的是Ubuntu 12.04 LTS,通过sudo apt-get install vim安装的版本较低,不支持YCM,所以,用源码编译并安装最新的Vim. 卸载旧版本的Vim: sudo ...
- echarts 通过源码方法 传入对应data数据获取分割步长值
通过源码方法获取这里的分割数字长度 /** * Quantity of a number. e.g. 0.1, 1, 10, 100 * * @param {number} val * @return ...
随机推荐
- Python——各类库的安装(持续更新)
一.BeautifulSoup 说明:www.crummy.com:Beautiful Soup 3只能在python2.x版本中运行,而Beautiful Soup 4还可以在python3.x版本 ...
- 题解 P1496 【火烧赤壁】
蒟蒻的第一篇题解,其实这道题是标准的离散化,模拟可以过,但是就没有训练效果了.我们首先先看数据,n<=20000,数据不多,但是范围大(-10^9<=Ai,Bi<=10^9),这时, ...
- svn 解决冲突
当svn update时提示如下: D C main.go > local file unversioned, incoming file add upon updateSummary of c ...
- Access-Control-Allow-Origin设置跨域
我来自己写一下答案,以给后来的朋友一点思路和建议:1,首先把Access-Control-Allow-Origin设置成*是不妥的,自己的接口服务器不能允许所有人都可以访问.2,具体哪里可以设置Acc ...
- Python文本编辑器推荐
首推当然是Sublime Text:可以中文化,百度上面有教程,页面比较酷炫,功能也不错 然后就是Notepad++,台湾开发,有中文界面
- 产品研发不等待 i.MX6Q全新推出增强版本 官方店铺下单双重优惠
迅为全新推出PLUS版本的i.MX6Q方案,版本介绍:它是NXP公司全新推出的i.MX6Q增强版新品,显著增强了图形和存储器性能,面向较高图形性能的先进消费电子.汽车和工业多媒体应用的多核平台.
- 2018-2019-2 20165234 《网络对抗技术》 Exp1 PC平台逆向破解
实验一 PC平台逆向破解 实验目的 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同时包含另 ...
- DC综合简单总结(1)
DC综合简单总结(1) *****************set_dont_touch和set_dont_touch_network**************** ? 在综合的过程中,为了不让D ...
- Win10如何彻底禁用小娜?彻底禁用小娜的方法
原文地址:https://www.cnblogs.com/zhuimengle/p/5949152.html 小娜是Win10系统中的一款强大功能,有了它,我们对电脑的操作将更加方便.Win10系统有 ...
- C# 常用类型校验Validate
using System.Text; using System.Text.RegularExpressions; namespace 落地页测试代码 { public class Validate { ...