当前位置: 首页 > 编程日记 > 正文

面试之Hashtable和ConcurrentHashMap

那么要如何保证HashMap的线程安全呢? 方法有很多,比如使用Hashtable或者Collections.synchronizedMap,但是这两位选手都有一个共同的问题:性能。因为不管是读还是写操作,他们都会给整个集合上锁,导致同一时间的其他操作被阻塞。


虽然Hashtable和Collections.synchronizedMap解决了HashMap的线程不安全的问题,但是带来了运行效率不佳的问题。


基于以上所述,兼顾了线程安全和运行效率的ConcurrentHashMap就出现了。

在了解了HashMap之后,接下来就开始了解一下ConcurrentHashMap。
ConcurrentHashMap与HashMap相比,最关键的是要理解一个概念:segment
Segment其实就是一个Hashmap 。Segment也包含一个HashEntry数组,数组中的每一个HashEntry既是一个键值对,也是一个链表的头节点。
Segment对象在ConcurrentHashMap集合中有2的N次方个,共同保存在一个名为segments的数组当中。(类比HashMap来理解Segment就好)

因此ConcurrentHashMap的结构为:
这里写图片描述
换言之,ConcurrentHashMap是一个双层哈希表。在一个总的哈希表下面,有若干个子哈希表。(这样的双层结构,类似于数据库水平拆分来理解)

ConcurrentHashMap如此的设计,优势主要在于:
每个segment的读写是高度自治的,segment之间互不影响。这称之为“锁分段技术”;

看一下并发情况下的ConcurrentHashMap:
情景一:不同segment的并发写入

这里写图片描述
不同的Segment是可以并发执行put操作的

情景二:同一segment的并发写入
这里写图片描述
因为segment的写入是上锁的,因此对 同一segment的并发写入会被阻塞;

情景三:同一segment的一写一读
这里写图片描述
同一segment的写和读是可以并发执行的;


看到此处,就已经知道了ConcurrentHashMap的并发情况,有兴趣的话可以继续看下ConcurrentHashMap的具体读写过程。

Get方法:

1.为输入的Key做Hash运算,得到hash值。

2.通过hash值,定位到对应的Segment对象

3.再次通过hash值,定位到Segment当中数组的具体位置。

Put方法:

1.为输入的Key做Hash运算,得到hash值。

2.通过hash值,定位到对应的Segment对象

3.获取可重入锁

4.再次通过hash值,定位到Segment当中数组的具体位置。

5.插入或覆盖HashEntry对象。

6.释放锁。


看到此处,对于ConcurrentHashMap的Get和Put的过程(读写过程)就有了一个完整的了解了。
基于上述,会有一个问题:
每一个segment各自持有锁,那么在调用size()方法的时候(size()在实际开发大量使用),怎么保持一致性呢
详细描述一下上面问题的情景:
Size方法的目的是统计ConcurrentHashMap的总元素数量, 肯定要把每个segment内部的元素数量都加起来
那么假设一种情况,在统计segment元素数量的过程中,在统计结束前,已统计过的segment插入了新的元素,size()返回的数量就会出现不一致的问题。
为解决这个问题,ConcurrentHashMap的Size()方法是通过一个嵌套循环解决的,大体过程如下:
1.遍历所有的Segment。

2.把Segment的元素数量累加起来。

3.把Segment的修改次数累加起来。

4.判断所有Segment的总修改次数是否大于上一次的总修改次数。如果大于,说明统计过程中有修改,重新统计,尝试次数+1;如果不是。说明没有修改,统计结束。

5.如果尝试次数超过阈值,则对每一个Segment加锁,再重新统计。

6.再次判断所有Segment的总修改次数是否大于上一次的总修改次数。由于已经加锁,次数一定和上次相等。

7.释放锁,统计结束。

这种解决办法是不是似曾相识?没错,这种思想和乐观锁悲观锁的思想如出一辙(不熟悉乐观锁的道友可以看我转的一篇非常生动的介绍,传送门)

为了不锁所有segment,首先乐观地假设size过程中不会有修改。当尝试一定次数,才无奈转悲观,锁住所有segment以保证一致性。

补充:
1、以上都是基于Java1.7的ConcurrentHashMap原理和代码;

2、ConcurrentHashMap在对Key求Hash值的时候进行了两次Hash,目的是为了实现Segment均匀分布。

小结


说了那么多,针对Map子类的安全性可以总结如下几点:

  • HashMap采用链地址法解决哈希冲突,多线程访问哈希表的位置并修改映射关系的时候,后执行的线程会覆盖先执行线程的修改,所以不是线程安全的
  • Hashtable采用synchronized关键字解决了并发访问的安全性问题但是效率较低
  • ConcurrentHashMap使用了线程锁分段技术,每次访问只允许一个线程修改哈希表的映射关系,所以是线程安全的

转载于:https://www.cnblogs.com/csong7876/p/9090779.html

相关文章:

PHP动态编译出现Cannot find autoconf

在安装完PHP后,想动态编译PHP的memcache扩展库 cd memcache-2.2.5//usr/local/webserver/php/bin/phpize./configure --with-php-config/usr/local/webserver/php/bin/php-config 但是执行/usr/local/webserver/php/bin/phpize时出现错误:Configuring for:PHP Api Version: …

AnimeGANv2 实现动漫风格迁移,简单操作

作者 | Yunlord出品 | CSDN博客前言之前一直在研究如何将图像动漫化,尝试了阿里云api和百度api,效果都不尽如人意。结果发现了一个宝藏github项目——AnimeGANv2,能够将现实世界场景照片进行动漫风格化。可以看出AnimeGAN的效果非常好&#x…

C#调用win32 api程序实例

1、声明static extern 方法,使用DllImport特性 class MyClass{[DllImport("kernel32", SetLastError true)]public static extern int GetCurrentDirectory(int a, StringBuilder b);} 2、调用 StringBuilder sbnew StringBuilder {Length 250}; MyClas…

Python 之 pip拒绝访问

起因 在我使用pip安装第三方库的时候,控制台提示我升级pip版本 You are using pip version 9.0.1, however version 10.0.1 is available. You should consider upgrading via the python -m pip install --upgrade pip command. 很显然,需要使用这样的指…

Unix / 类 Unix shell 中有哪些很酷很冷门很少用很有用的命令?(转)

著作权归作者所有。 商业转载请联系作者获得授权,非商业转载请注明出处。 作者:孙立伟 链接:http://www.zhihu.com/question/20140085/answer/14107336 来源:知乎 这个问题quora上有人提过 What are some lesser known but useful…

干货满满的 Python 实战项目,点赞收藏

作者 | 俊欣来源 | 关于数据分析与可视化今天小编来给大家介绍3个干货满满的计算机视觉方向的Python实战项目,主要用到的库有opencv-pythonnumpypillow要是大家所配置的环境当中没有这几个模块的话,就需要先用pip命令下载安装pip install opencv-python …

php安装完成以后要复制php.ini文件

直接 #find / -name "php.ini" 找不到,是因为安装php的时候没有复制配置文件 php版本变化以后ini文件名有变 php.ini-production对应于php.ini-recommended php.ini-development对应于php.ini-dist二者差异? 由于版本更新,这些文件有了新的命…

MASQUERADE --random 端口不随机

iptables -t nat -A POSTROUTING -o xxxx -j MASQUERADE --random发现源端口并不是随机的而是有规律递增,经过Google的搜索查找,发现新的版本有--random-full 这个参数iptables -t nat -A POSTROUTING -o xxxx -j MASQUERADE --random-full经过测试端口随…

PHP安装与使用VLD查看opcode代码【PHP安装第三方扩展的方法】

需要分析PHP代码的性能,或者说实现同样功能的代码到底哪个更好呢?或者说想知道底层的实现可以使用VLD查看opcode 下载与安装VLD # wget http://pecl.php.net/get/vld-0.11.2.tgz# tar zxvf vld-0.11.2.tgz# cd ./vld-0.11.2# /usr/local/php/bin/phpize …

实现数组字符串翻转的两种方法

//第一种方法&#xff1a;递归法 #include <stdio.h> int reverse_string(char * string) {if (*string ! \0){reverse_string(string1);printf("%c", *string);} } int main() {char *string "abcde";printf("源字符串为&#xff1a;%s\n&quo…

详解 Python 如何将爬取到的数据分别存储到 txt、excel、mysql 中!

作者 | 黄伟呢来源 | 数据分析与统计学之美1. 页面分析我爬取的页面是腾讯体育&#xff0c;链接如下&#xff1a;https://nba.stats.qq.com/player/list.htm观察上图&#xff1a;左边展示的分别是NBA的30支球队&#xff0c;右边就是每只球队对应球员的详细信息。此时思路就很清…

蹭了BCH热度,还来诋毁BCH,这些跳梁小丑到底在玩什么阴谋?

最近一些分叉币为了博眼球简直什么招数都用。有的某分叉币对主链暂停10天的问题闭口不提&#xff0c;靠微博撕逼来吸引关注&#xff0c;有的则自导自演了一出51%***的大戏。而奇怪的是当别人开始谈论他们这些错误的时候&#xff0c;他们却把矛头指向了火热的比特币现金。这些跳…

比 GPT-3 更擅长理解用户意图,OpenAI发布 InstructGPT

作者 | 青苹果来源 | 数据实战派近日&#xff0c;OpenAI 发布了一项令人瞩目的研究—— InstructGPT。在这项研究中&#xff0c;相比 GPT-3 而言&#xff0c;OpenAI 采用对齐研究&#xff08;alignment research&#xff09;&#xff0c;训练出更真实、更无害&#xff0c;而且更…

The C10K problem原文翻译

原文地址&#xff1a;http://www.cnblogs.com/fll/archive/2008/05/17/1201540.htmlThe C10K problem如今的web服务器需要同时处理一万个以上的客户端了&#xff0c;难道不是吗&#xff1f;毕竟如今的网络是个big place了。 现在的计算机也很强大了&#xff0c;你只需要花大概$…

mysql中模糊查询的四种用法介绍

下面介绍mysql中模糊查询的四种用法&#xff1a; 1&#xff0c;%&#xff1a;表示任意0个或多个字符。可匹配任意类型和长度的字符&#xff0c;有些情况下若是中文&#xff0c;请使用两个百分号&#xff08;%%&#xff09;表示。 比如 SELECT * FROM [user] WHERE u_name LIKE …

spring data jpa 详解

2019独角兽企业重金招聘Python工程师标准>>> 本篇进行Spring-data-jpa的介绍&#xff0c;几乎涵盖该框架的所有方面&#xff0c;在日常的开发当中&#xff0c;基本上能满足所有需求。这里不讲解JPA和Spring-data-jpa单独使用&#xff0c;所有的内容都是在和Spring整…

php使用curl可以get 模拟post

本机windows测试需要打开curl php.ini extensionphp_curl.dll重启apacheinclude (Curl.php);$cunew QP_Curl_Curl();$s$cu->get(http://www.baidu.com);echo $s;Curl.php可以使用http://www.myquickphp.com/的框架中的组件Curl.php/*** CURL 工具* * category QuickPHP(II…

为什么使用模块?

# -*- coding: utf-8 -*- #python 27 #xiaodeng #模块01#每个文件都是一个模块&#xff0c;并且模块导入之后就可以导入模块定义的变量名。#为什么使用模块&#xff1f; #命名空间提供了将部件组织为系统的简单的方法。 #在一个模块文件的顶层定义的所有变量名都成了被导入的模…

报告!插件×元宵来啦

欢欢喜喜 闹元宵迈过新年&#xff0c;开工大吉&#xff0c;元宵节的脚步悄悄靠近&#xff0c;在大家努力搬砖得同时&#xff0c;CSDN插件带着它的元宵活动走来啦~元宵喜乐汇虎年的第一个月圆之夜&#xff0c;除了吃汤圆还能干啥呢&#xff1f;当然是猜灯谜咯&#xff01;CSDN插…

%f%g%e区别

%f 表示按浮点数的格式输出 %e 表示按指数形式的浮点数的格式输出 %g 表示自动选择合适的表示法输出&#xff0c;可以去小数末尾多余的0转载于:https://www.cnblogs.com/holyday/p/9111777.html

Cassandra安装测试

说明&#xff0c;本人成功安装过程记录 只要看解压目录的readme.txt即可&#xff0c;其他网上教程由于版本不对会执行报错&#xff0c;例如遇到编码问题 #wget http://www.apache.org/dyn/closer.cgi?path/cassandra/1.0.3/apache-cassandra-1.0.3-bin.tar.gz #tar -zxvf a…

如何使用 Python 隐藏图像中的数据

作者 | 小白来源 | 小白学视觉隐写术是在任何文件中隐藏秘密数据的艺术。秘密数据可以是任何格式的数据&#xff0c;如文本甚至文件。简而言之&#xff0c;隐写术的主要目的是隐藏任何文件&#xff08;通常是图像、音频或视频&#xff09;中的预期信息&#xff0c;而不实际改变…

php 的 危 险 参 数

hpinfo() 功能描述&#xff1a;输出 PHP 环境信息以及相关的模块、WEB 环境等信息。 危险等级&#xff1a;中 passthru() 功能描述&#xff1a;允许执行一个外部程序并回显输出&#xff0c;类似于 exec()。 危险等级&#xff1a;高 exec() 功能描述&#xff1a;允许执行一个外部…

开源 | 蚂蚁金服分布式中间件开源第二弹:丰富微服务架构体系

小蚂蚁说&#xff1a; 数据、消息、微服务是蚂蚁金服自主研发的金融级分布式中间件 SOFA &#xff08;Scalable Open Financial Architecture&#xff09;的三大方向。 一个多月前&#xff0c;蚂蚁金服开源了 SOFABoot 和 SOFARPC 两个组件&#xff0c;受到了社区的热烈欢迎&am…

System.Web.Caching.Cache类 缓存 各种缓存依赖

原文:System.Web.Caching.Cache类 缓存 各种缓存依赖Cache类&#xff0c;是一个用于缓存常用信息的类。HttpRuntime.Cache以及HttpContext.Current.Cache都是该类的实例。 一、属性 属性说明Count获取存储在缓存中的项数。EffectivePercentagePhysicalMemoryLimit获取在 ASP.NE…

Python 可视化近 90 天的百度搜索指数 + 词云图

作者 | 叶庭云来源 | AI庭云君一、简介 在实际业务中我们可能会使用爬虫根据关键词获取百度搜索指数历史数据&#xff0c;然后进行对应的数据分析。百度指数&#xff0c;体验大数据之美。但要获取百度指数相关的数据&#xff0c;困难如下&#xff1a;不是静态网页&#xff0c;并…

php常用比较函数区别表

php常用比较函数区别表 表达式 empty() is_null() isset() if($x) $x "" TRUE FALSE TRUE FALSE $x null TRUE TRUE FALSE FALSE $x is undefined TRUE TRUE FALSE FALSE(报E_NOTICE错) $x array() TRUE FALSE TRUE FALSE $x false TRUE FALSE TRUE FALSE $x 0 …

实战分享:淘宝Web 3D应用与游戏开发

大家下午好&#xff01;我们今天讲个比较有意思的话题&#xff0c;这个话题在业界被谈及得比较少。大家在座有做过移动端开发的同学吗&#xff1f;请举个手&#xff0c;人还挺多的。那做过3D应用的同学请举个手&#xff0c;有用过Threejs的请举个手&#xff0c;做过游戏的呢..人…

常见NoSQL系统使用场景分析

•Cassandra •特性&#xff1a;分布式与复制的权衡\根据列和键范围进行查询\BigTable类似的功能&#xff1a;列&#xff0c;列族\写比读快很多 •最佳适用&#xff1a;写操作较多&#xff0c;读比较少的时候。如果你的系统都是基于Java的时候。 •应用场景&#xff1a;银行&am…

再一次输给了AI,弯道急速超车、登上 Nature 封面

作者 | 学术头条来源 | 学术头条人工智能&#xff08;AI&#xff09;的很多潜在应用&#xff0c;涉及与人类交互时做出更优化的实时决策&#xff0c;而竞技或者博弈类游戏&#xff0c;便是最佳的展示舞台。近日&#xff0c;发表在《自然》杂志上的封面文章报告称&#xff0c;AI…