并发编程(六)

1、HashMap、HashTable、ConcurrentHashMap的比较

HashMap、HashTable和ConcurrentHashMap是Java中的几种重要的数据结构,它们都可以用来存储键值对。但是,它们之间存在一些重要的差异,尤其是在线程安全和性能方面。以下是它们之间的比较:

①线程安全:

HashMap:是非线程安全的。如果多个线程同时修改HashMap,那么它不会提供任何形式的同步。

HashTable:是线程安全的。它的所有公共方法都是同步的,因此一次只有一个线程可以访问这个表。

ConcurrentHashMap:也是线程安全的,但它比HashTable更高效。ConcurrentHashMap使用了分段锁技术,这意味着它的大部分操作(如get和put)都是线程安全的,即使在并发环境下也不会阻塞。

②性能:

HashMap:在单线程环境下通常有最好的性能,因为它不需要进行任何同步。

HashTable:在多线程环境下,由于其同步机制,性能可能会受到影响。

ConcurrentHashMap:在多线程环境下提供了更好的性能,因为它使用了分段锁技术,减少了锁的竞争。

③初始容量和加载因子:

HashMap 和 HashTable:允许你设置初始容量和加载因子,但它们通常需要手动调整。

ConcurrentHashMap:内部实现了动态调整大小的功能,因此通常不需要手动设置这些参数。

④迭代器:

HashMap 和 HashTable:迭代器是弱一致性的,意味着它们不会抛出ConcurrentModification Exception。但是,迭代器并不保证能反映出在迭代过程中对映射所做的修改。

ConcurrentHashMap:迭代器也是弱一致性的,类似于HashMap和HashTable。但是,它提供了一种称为“条件性弱一致性”的迭代器,可以安全地用于几乎所有并发修改的情况。

⑤null键和值:

HashMap 和 HashTable:允许null键和值。

ConcurrentHashMap:不允许null键和值。

⑥访问顺序:

HashMap 和 HashTable:不保证元素的访问顺序。

ConcurrentHashMap:提供了一种基于红黑树的并发哈希映射实现,因此它可以保证元素的有序性。但是,这并不是通过锁机制实现的,而是在内部使用了更复杂的算法。

2、HashMap的实现原理(jdk1.7与jdk1.8对比)

HashMap是Java中常用的数据结构之一,它使用哈希表来存储键值对。在JDK 1.7和JDK 1.8中,HashMap的实现原理有所不同,主要体现在扩容、冲突解决和数据结构优化等方面。

在JDK 1.7中,HashMap使用数组+链表的方式实现。当发生哈希冲突时,将链表存储在同一个数组位置上。当数组容量超过一定阈值(默认为8)时,会对数组进行扩容。扩容后,需要重新计算所有元素的哈希值,并将元素重新放入新的数组中。此外,JDK 1.7中的HashMap不支持null键和null值。

在JDK 1.8中,HashMap进行了许多优化和改进。首先,它使用数组+链表+红黑树的方式实现,以提高搜索效率。当链表长度超过一定阈值(默认为8)时,将链表转换为红黑树。此外,JDK 1.8中的HashMap扩容更加高效,扩容后不再需要重新计算所有元素的哈希值。此外,JDK 1.8中的HashMap还支持null键和null值。

3、HashMap扩容会导致的问题

HashMap扩容会导致一些问题,主要包括性能下降和死循环问题。

  1. 性能下降:当HashMap需要扩容时,需要重新计算所有元素的哈希值,并将元素重新放入新的数组中。这个过程需要消耗大量的计算资源,并且会阻塞其他线程对哈希表的访问。因此,在扩容期间,HashMap的性能会显著下降。
  2. 死循环问题:在JDK 1.7中,HashMap扩容后使用了头插法将元素插入到新的数组中,可能会导致出现环链问题。在多个线程同时进行扩容操作的情况下,可能会出现一个线程已经完成扩容操作,而另一个线程还在进行扩容操作的情况。此时,如果使用头插法插入元素,可能会出现环链问题,导致死循环。

为了避免这些问题,可以使用ConcurrentHashMap代替HashMap,因为ConcurrentHashMap使用了分段锁技术,可以避免锁竞争和死循环问题。同时,也可以预先指定HashMap的初始容量,以减少扩容的频率,提高性能。

4、ConcurrentHashMap的实现原理(jdk1.7与jdk1.8对比)

ConcurrentHashMap是Java中线程安全的哈希表实现,它在JDK 1.7和JDK 1.8中也有一些不同的实现原理和优化。

在JDK 1.7中,ConcurrentHashMap使用分段锁技术实现线程安全。它将整个哈希表分成若干个段(Segment),每个段都是一个小的哈希表。对某个段进行操作时,只需要对该段加锁,不会阻塞其他线程对其他段的访问。这种实现方式可以显著提高并发性能,因为多个线程可以同时访问不同的段。但是,由于每个段都是一个小的哈希表,因此在高并发情况下,可能会存在热点数据问题,即多个线程同时访问同一个段,导致锁竞争激烈。

在JDK 1.8中,ConcurrentHashMap进行了许多优化和改进。首先,它使用红黑树实现哈希表的平衡搜索。当链表长度超过一定阈值(默认为8)时,将链表转换为红黑树,提高搜索效率。此外,JDK 1.8中的ConcurrentHashMap还使用了锁分段技术,将整个哈希表分成若干个桶(Bucket),每个桶都对应一个锁。这种技术可以提高并发性能,同时避免热点数据问题。此外,JDK 1.8中的ConcurrentHashMap还使用了一种称为“写前通知”(Write-Ahead Notification)的机制,可以提高并发写操作的性能。

5、为什么要使用ConcurrentHashMap

在并发编程中使用HashMap可能导致程序死循环。而使用线程安全的HashTable效率又非

常低下,基于以上两个原因,便有了ConcurrentHashMap的登场机会。

(1)线程不安全的HashMap

在多线程环境下,使用HashMap进行put操作会引起死循环,导致CPU利用率接近100%,所

以在并发情况下不能使用HashMap。例如,执行以下代码会引起死循环。

HashMap在并发执行put操作时会引起死循环,是因为多线程会导致HashMap的Entry链表

形成环形数据结构,一旦形成环形数据结构,Entry的next节点永远不为空,就会产生死循环获

取Entry。

(2)效率低下的HashTable

HashTable容器使用synchronized来保证线程安全,但在线程竞争激烈的情况下HashTable

的效率非常低下。因为当一个线程访问HashTable的同步方法,其他线程也访问HashTable的同

步方法时,会进入阻塞或轮询状态。如线程1使用put进行元素添加,线程2不但不能使用put方

法添加元素,也不能使用get方法来获取元素,所以竞争越激烈效率越低。

(3)ConcurrentHashMap的锁分段技术可有效提升并发访问率

HashTable容器在竞争激烈的并发环境下表现出效率低下的原因是所有访问HashTable的

线程都必须竞争同一把锁,假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么

当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效提高并

发访问效率,这就是ConcurrentHashMap所使用的锁分段技术。首先将数据分成一段一段地存

储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数

据也能被其他线程访问。

6、java中的阻塞队列

ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列。

·LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列。

·PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。

·DelayQueue:一个使用优先级队列实现的无界阻塞队列。

·SynchronousQueue:一个不存储元素的阻塞队列。

·LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。

·LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。

7、Fork/Join框架

一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。

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

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

相关文章

Python 基础(八):函数

1 简介 简单来说函数就是一段实现特定功能的代码,使用函数可以提高代码的重复利用率。Python 中有很多内置函数,比如之前常用的 print 函数,当内置函数不足以满足我们的需求时,我们还可以自定义函数。 2 自定义函数 Python 使用…

JDK21和 Flowable 7.0.0

JDK21和 Flowable 7.0.0 一.Flowable二.项目搭建1.依赖包2.数据库3.资源文件1.YML配置文件2.Drools kbase3.Drools rule4.DMN 决策表5.BPMN 流文件 4.BPMN 流程图绘制插件5.测试代码1.启动类2.Flowable 配置3.Camel 配置1.Camel 配置2.Camel Router 定义 4.扩展类监听1.外部工作…

SOP-8 SOIC-8 SO-8封装区别

学习自记: SO8和SO-8封装是相同的,SOP8和SOP-8封装也是相同的。SO8封装与SOP8封装的尺寸稍有差异,但差别不大。在 PCB 板上,这两种封装之间没有区别。 SOP也是一种很常见的封装形式,始于70年代末期。SOP封装的应用范围…

docker compose安装gitlab

环境 查看GitLab镜像 docker search gitlab 拉取GitLab镜像 docker pull gitlab/gitlab-ce 准备gitlab-docker.yml文件 version: 3.1 services:gitlab:image: gitlab/gitlab-ce:latestcontainer_name: gitlabrestart: alwaysenvironment:GITLAB_OMNIBUS_CONFIG: |external_url…

在Windows Server 2012中部署war项目

目录 一.安装jdk 二.安装tomcat 三.安装MySQL 四.部署项目 好啦今天就到这了,希望帮到你了哦 前言:具体步骤: 1.安装JDK: 2.安装tomcat: 3.安装MySQL: 4.部署项目: 一.安装jdk 将所需文件放…

苍穹外卖学习----出错记录

1.微信开发者工具遇到的问题: 1.1appid消失报错: {errMsg: login:fail 系统错误,错误码:41002,appid missing [20240112 16:44:02][undefined]} 1.2解决方式: appid可在微信开发者官网 登录账号后在开发栏 找到 复制后按以下步骤粘贴即…

2024.1.4力扣每日一题——被列覆盖的最多行数

2024.1.4 题目来源我的题解方法一 回溯位运算优化 题目来源 力扣每日一题;题序:2397 我的题解 方法一 回溯位运算优化 这道题一看就会想到使用回溯法,但是采用回溯法后如何判断有多少行被覆盖,直接计算矩阵时间复杂度较高&…

怎么将文件批量重命名为不同名称?

怎么将文件批量重命名为不同名称?有许多情况下可以考虑对文件进行批量重命名为不同名称,文件分类和整理:当您需要对一组文件进行分类、整理或重新组织时,可以考虑将它们批量重命名为不同的名称。这有助于更好地组织文件并使其更易…

提升测试多样性,揭秘Pytest插件pytest-randomly

大家可能知道在Pytest测试生态中,插件扮演着不可或缺的角色,为开发者提供了丰富的功能和工具。其中,pytest-randomly 插件以其能够引入随机性的特性而备受欢迎。本文将深入探讨 pytest-randomly 插件的应用,以及如何通过引入随机性…

在线项目实习分享:股票价格形态聚类与收益分析

01前置课程 数据挖掘基础数据探索数据预处理数据挖掘算法基础Python数据挖掘编程基础Matplotlib可视化Pyecharts绘图 02师傅带练 行业联动与轮动分析 通过分析申银万国行业交易指数的联动与轮动现象,获得有意义的行业轮动关联规则,并在此基础上设计量…

树莓派 gpio 安装及简单使用

安装 git clone https://github.com/WiringPi/WiringPi cd WiringPi/ ./build查看版本 gpio -v gpio version: 2.70列出io gpio readall-----------------------------Model B1-----------------------------| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name…

【NI-DAQmx入门】LabVIEW中DAQmx同步

1.同步解释 1.1 同步基础概念 触发器:触发器是控制采集的命令。您可以使用触发器来启动、停止或暂停采集。触发信号可以源自软件或硬件源。 时钟:时钟是用于对数据采集计时的周期性数字信号。根据具体情况,您可以使用时钟信号直接控制数据采…

并发编程(十一)

性能测试的常用命令 1、Netstat是在内核中访问网络连接状态及其相关信息的程序,它能够显示协议统计和当前TCP/IP的网络连接。 Netstat命令的常用格式如下: netstat -a:显示所有网络连接和侦听端口。 netstat -b:显示在创建网络…

基于SSM的驾校预约管理系统

基于SSM的驾校预约管理系统的设计与实现~ 开发语言:Java数据库:MySQL技术:SpringSpringMVCMyBatis工具:IDEA/Ecilpse、Navicat、Maven 系统展示 主页 详情 管理员界面 摘要 随着社会的不断发展,驾驶技能的需求逐渐增…

什么是 CAS

程序员的公众号:源1024,获取更多资料,无加密无套路! 最近整理了一波电子书籍资料,包含《Effective Java中文版 第2版》《深入JAVA虚拟机》,《重构改善既有代码设计》,《MySQL高性能-第3版》&…

Pandas实战100例 | 案例 5: 数据过滤 - 使用条件过滤数据

案例 5: 数据过滤 - 使用条件过滤数据 知识点讲解 数据过滤是数据分析中的常见需求,它允许你基于一定条件从数据集中筛选出感兴趣的数据子集。 示例代码 基于单个条件过滤 # 筛选出某列值大于特定值的所有行 filtered_data df[df[Column] > 10] print(filt…

第一波!2024年1月精选6款实用AI人工智能设计工具合集

大家好,这是进入2024年之后的第一波干货合集!这次的干货合集还是以 AI 相关的设计干货开头,这次有了在本地无限制帮你清理图片中元素的 AI 工具,有知名免费图库出品的实时 AI 图片生成工具、将截图直接转化为代码的超强工具&#…

公司官网,选全站定制还是模板建站?

最近更新了公司网站,总算了了一件大事。 虽然很久以前也做网站,但随着技术的发展,以前经常用的dreamwaver、table等形式,不知道被升级了多少代。现在前端同事说起的各种架构,对我来说是云里雾里。只能看懂一点点。 这…

yolov5 7.0中文注释版train.py和detect.py

为了更好的学习,最近给yolov5 7.0版本的train和detect.py增加了中文注释,注释的部分内容如下,仅展示部分注释 detect.py的部分代码展示 # 版本说明:该版本是yolov5-7.0,由微智启软件工作室添加中文注释,给…

API设计:从基础到优秀实践

在这次深入探讨中,我们将深入了解API设计,从基础知识开始,逐步进阶到定义出色API的最佳实践。 作为开发者,你可能对许多这些概念很熟悉,但我将提供详细的解释,以加深你的理解。 API设计:电子商…