Java 并发---ConcurrentHashMap

concurrent包下的并发容器

JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能。因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法的代价就是严重降低了并发性,当多个线程竞争容器时,吞吐量严重降低。因此Java5开始针对多线程并发访问设计,提供了并发性能较好的并发容器,引入了java.util.concurrent包。

与Vector、HashTable、Collections.synchronizedXxx()等同步容器相比,util.concurrent中引入的并发容器主要解决了两个问题:

  1. 根据具体场景进行设计,尽量避免synchronized,提供并发性。
  2. 定义了一些并发安全的复合操作,并且保证并发环境下的迭代操作不会出错。

util.concurrent中容器在迭代时,可以不封装在synchronized中,可以保证不抛异常,但是未必每次看到的都是"最新的、当前的"数据。

下面是对并发容器的简单介绍:

ConcurrentHashMap代替同步的Map(Collections.synchronized(new HashMap())),众所周知,HashMap是根据散列值分段存储的,同步Map在同步的时候锁住了所有的段,而ConcurrentHashMap加锁的时候根据散列值锁住了散列值锁对应的那段,因此提高了并发性能。ConcurrentHashMap也增加了对常用复合操作的支持,比如"若没有则添加":putIfAbsent(),替换:replace()。这2个操作都是原子操作。

CopyOnWriteArrayList和CopyOnWriteArraySet分别代替List和Set,主要是在遍历操作为主的情况下来代替同步的List和同步的Set,这也就是上面所述的思路:迭代过程要保证不出错,除了加锁,另外一种方法就是"克隆"容器对象。

ConcurrentLinkedQueue是一个先进先出的队列。它是非阻塞队列。

ConcurrentSkipListMap可以在高效并发中替代SortedMap(例如用Collections.synchronizedMap包装的TreeMap)。

ConcurrentSkipListSet可以在高效并发中替代SortedSet(例如用Collections.synchronizedSet包装的TreeMap)。

为什么使用ConcurrentHashMap

线程不安全的HashMap

并发编程中使用HashMap可能导致程序死循环,导致cpu利用率接近100%。具体原因是,再执行put操作时会引起死循环,多线程会导致HashMap的Entry链表形成环形数据结构,这样的话Entry的next节点永远不为空,就会产生死循环获取Entry。

效率低下的HashTable

HashTable使用synchronized来保证线程安全,竞争激烈情况下,当一个线程访问同步方法,其他线程也访问同步方法,会进入阻塞或轮询状态。线程1使用put进行元素添加,线程2不但不能使用put方法,也不能使用get方法。

ConcurrentHashMap使用锁分段技术

ConcurrentHashMap将数据分成一段一段地存储,然后给每一段数据配一把锁,并且其内部的结构可以让其在进行写操作的时候能够将锁的粒度保持尽量的小,不用对整个ConcurrentHashMap加锁。当一个线程占用锁访问其中一个段数据的时候,其他段地数据也能被其他线程访问。

ConcurrentHashMap的结构

ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成。Segment是一种可重入锁ReentrantLock,在ConcurrentHashMap里扮演锁的角色,HashEntry则用于存储键值对数据。一个ConcurrentHashMap里包含一个Segment数组,Segment的结构和HashMap类似,是一种数组和链表结构, 一个Segment里包含一个HashEntry数组,每个HashEntry是一个链表结构的元素, 每个Segment守护着一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segment锁。
ConcurrentHashMap结构图

ConcurrentHashMap和HashTable的区别图
ConcurrentHashMap和HashTable的区别图

从上面的结构我们可以了解到,ConcurrentHashMap定位一个元素的过程需要进行两次Hash操作,第一次Hash定位到Segment,第二次Hash定位到元素所在的链表的头部,因此,这一种结构的带来的副作用是Hash的过程要比普通的HashMap要长,但是带来的好处是写操作的时候可以只对元素所在的Segment进行加锁即可,不会影响到其他的Segment,这样,在最理想的情况下,ConcurrentHashMap可以最高同时支持Segment数量大小的写操作(刚好这些写操作都非常平均地分布在所有的Segment上),所以,通过这一种结构,ConcurrentHashMap的并发能力可以大大的提高。

转载于:https://www.cnblogs.com/hesier/p/5929626.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/256275.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图像处理】——图像滤波(Python+opencv实现三种方法:均值滤波、中值滤波、高斯滤波等)

目录 一、什么是滤波以及滤波的目的? 二、均值滤波(cv2.blur()) 1、原理 2、关键代码

UIScrollView事件拦截

在日常的开发中,我们经常会用到UIScrollView,然而,它是一个问题频出的控件,比如在nib中使用它就必须手动为它创建一个ContentView.当然了使用春代码的时候使用了懒加载机制使得它能够拥有一个contentView,今天我们不谈这个问题,我们来谈谈UIScrollView的事件拦截相关的知识. 在…

Windows10下安装QT5.14.2并用VS2019打开

安装 从官网下载:QT 安装方法仅需要注意: 1.最好不要安装在C盘。 2.根据开发需要安装功能模块,具体见参考文章。 https://jingyan.baidu.com/article/656db918d9292ae380249c4f.html 因为是用于PCL编程的,所以只选了msvc2017_64,…

【图像处理】——图像质量评价指标信噪比(PSNR)和结构相似性(SSIM)(含原理和Python代码)

目录 一、信噪比(PSNR) 1、信噪比的原理与计算公式 2、Python常规代码实现PSNR计算 3、TensorFlo

Error和Exception的区别

Error:值得是指与虚拟机相关的问题,比如虚拟机崩溃,虚拟机错误,内存空间不足,方法调用栈溢出。 对于这类错误应建议中断。 Exception:是指程序员可以处理的异常,可以捕获并且能够恢复&#xf…

JAVA TCP/IP网络通讯编程(二)

一个实例通过client端和server端通讯 客户端通过TCP/IP传输资源文件,比如图片,文字,音频,视频等..... 服务端接受到文件存入本地磁盘,返回接受到:“收到来自于"s.getInetAddress().getHostName()"…

C#中json序列化与反序列化

json格式概念 JSON(JavaScript Object Notation) 是一种轻量级的数据传输格式,其采用完全独立于语言的文本格式,使JSON成为理想的数据交换语言。 json由两种格式组成。 1.名称/值”对的集合,可以一起创建多个"名称 / 值对"。 { “…

volley用法之 以post方式发送 json 参数

需求是这样 我们需要发送一个post请求向服务器要参数。要求是发送的post参数也要是json格式。 简单一点的是这样的: 如果要发送的是这样简单的json格式,我们可以简单的使用map来实现: RequestQueue requestQueue Volley.newRequestQueue(get…

我的友情链接

小小忍者Tab转载于:https://blog.51cto.com/12737170/2043087

JAVA 文件编译执行与虚拟机(JVM)简单介绍

详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytpo3 java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机。只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任…

C#中数据流(文件流、内存流、网络流等)相关知识点梳理

基本概念 C#中数据流的应用体现在方方面面,现在针其常用的几种类进行一次梳理。 数据流包括文件流(FileStream)、内存流(MemoryStream)、网络流(NetworkStream)以及读写流如StreamReader、StreamWriter、BinaryReader和BinaryWriter等。 数据流是什么? …

dns服务 很多问题,后续再研究

慕课网:http://www.imooc.com/video/5220 参考:http://jingyan.baidu.com/article/870c6fc32c028eb03fe4be30.html http://www.tuicool.com/articles/aUNzMfi http://www.07net01.com/linux/dnszhucongfuzhijiquyuchuansong_505144_1373161402.html http…

LINUX下用脚本实现JDK+TOMCAT

这几天真是累。常常下半夜3点睡觉。是因为这段时间对LINUX下的SHELL编程喜欢上了。 一时弄的忘了睡觉。还好,累没白累。遍写了一个JDKTOMCAT的自动安装,配置的脚本 在这里我把配置出来的成果拿来和大家分享一下。希望有高手来指定一下,我在编…

【图像处理】——图像增强Python实现直方图均衡化

目录 一、相关概念 1、灰度直方图概念(hist) 2、灰度概率累积函数(cdf) 3、灰

C#常见编码方式总结

一、概念 我们知道计算机是基于二进制来表示数据的,那么对于字母和汉字等字符用二进制如何表示? 这就需要用一种编码方式将这些字母或者符号转换二进制表示。首先需要对字符集进行编码表示,每个编码代表一个固定的字符,然后再将字…

Spring中ApplicationContext加载机制

详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp33 加载器目前有两种选择:ContextLoaderListener和ContextLoaderServlet。 这两者在功能上完全等同,只是一个是基于Servlet2.3版本中新引入的Listener接口实现,…

Codeforces 724 C. Ray Tracing

Codeforces 724 C. Ray Tracing 题目来源 codeforces 题意: 有一些传感器按输入坐标分布在图上,有一道光从(0,0)沿45角出射,遇到边按反射法则反射,遇到角落结束。 问每一个点被经过的时间,并按照输入顺序输出。题解&am…

CDN架构以及原理分析

详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp61 在不同地域的用户访问网站的响应速度存在差异,为了提高用户访问的响应速度、优化现有Internet中信息的流动,需要在用户和服务器间加入中间层CDN. 使用户能以最快的速度,从最接近用…

基于VS2019的Eigen库安装详解

概念 Eigen是一个C开源线性代数库,以提供有关矩阵的的线性代数运算,解方程等功能。Eigen在很多领域如信号处理,图像处理,深度学习等起到重要作用,学习其操作方法,可以灵活的对线性代数、矩阵和矢量将进行计…