【JavaEE】线程安全的集合类

作者主页:paper jie_博客

本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。

本文于《JavaEE》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将基础知识一网打尽,希望可以帮到读者们哦。

其他专栏:《MySQL》《C语言》《javaSE》《数据结构》等

内容分享:本期将会分享线程安全的集合类芝士

目录

引入

多线程使用ArrayList

多线程使用队列

多线程使用哈希表

Hashtable

ConcurrentHashMap

 相关面试题


引入

之前我们所学的集合类,大多数都是线程不安全的.,像ArrayList,LinkedList,Queue等都是线程不安全的.这里我们将介绍`线程安全的类

多线程使用ArrayList

1.可以自己使用synchronized来加锁实现线程安全

2.Collections.synchronizedList(new ArrayList);

它就相当于给ArrayList套了一个壳,通过这个壳得到了一个新的对象,这个新的对象的关键方法就加上了synchronized.

3.使用CopyOnWritArrayList

当我们放容器中添加元素时,不会往旧容器中添加,而是会将当前这个容器的数据拷贝到一个新的容器中.添加完元素后,在将原有容器的引用指向新的容器.

它带来的好处就是我们可以对CopyWritArrayList容器进行并发的读,不需要加锁,因为当前容器不会添加任何元素.

优点就是在读多写少的场景下,性能很高,不需要加锁.

缺点就是比较占用内存,新写的数据不能第一时间读到.且不适用与写多的场景.

多线程使用队列

1.ArrayListBlockingQueue

2.LinkedListBlockingQue

3.priorityBlockingQueue

4.TransferQueue

只包含一个元素的阻塞队列.

多线程使用哈希表

Hashtable

在数据结构中,我们学过hashmap和hashset,这两者本身其实是线程不安全的.在所线程的环境下我们就可以使用Hashable和CouncurrentHashMap.

而我们的Hashtable就是在关键方法中加上了synchronized关键字,这其实就是直接对Hashtable对象本身直接加锁.这就会出现一些问题:

如果多个线程访问同一个Hashtable就会造成锁冲突.

size属性也是被synchronized控制,这样锁冲突会进一步加大.

一但触发扩容,就会由该线程来完成扩容过程,这个过程机会涉及到大量的元素拷贝,这里的速度就会很慢.

一个Hashtable就只有一个锁,只要有两个线程访问这个HashTable中的任意一个数据就会发生锁竞争.这里读操作和其他链表的元素是不会发生线程安全问题的,但是这里还是会有锁.

ConcurrentHashMap

相比于Hashtable,ConcurrentHashMap就做出了一系列的改进和优化.这里以Java1.8为例:

1. 读操作没有加锁,只是使用了volatile保证从内存读取结果,只对写操作进行加锁.加锁的方式仍然是使用synchronized,只不过它加锁的不是整个对象,而是"锁桶",这就是每一个链表,这里用每个链表的头节点来作为锁对象,这样就大大降低了锁冲突的概率.

2. 充分的利用了CAS特性.size属性就是使用CAS来更新的,这样就又降低了锁冲突的概率.

3. 优化了扩容方法,采用的是化整为零.

发现需要扩容的线程,只需要创建出一个数组,再搬运少量元素过去即可.

扩容期间,新老数组同时存在

后面每个操作ConcurrentMap的线程都会参与搬运数组的任务,每个操作都会搬运一小部分

直到搬运完最后一个元素再将老数组删除.

这个期间插入元素只往新数组中插入.

这个期间查找删除元素新数组和老数组都需要查找和删除.

 相关面试题

1. ConcurrentHashMap的读是否要加锁?

读不需要加锁,这样可以减少锁冲突.但是为了及时读到刚修改的数据,搭配了volatile关键字.

2. 介绍ConcurrentHashMap的分段技术?

这是Java1.7中采用的技术.Java1.8中已经不再使用了.它就是将若干个链表分成一个段,给段加上锁,目的还是为了降低锁竞争的概率.当两个线程访问的数据在一个段中就会发生锁竞争. 

3.ConcurrentHashMap在jdk1.8做了哪些优化?

取消了分段锁,直接给每个哈希桶每个链表分配了一个锁.将原来数组+链表的实现方式改变为数组+链表+红黑树的方式.当链表大于等于8时就会由链表转变为红黑树. 

4.Hashtable和HashMap,ConcurrentHashMap的区别?

HashMap: 线程不安全,key可以为null

Hashtable: 线程安全,使用synchronized锁加在Hashtable对象上,效率低.且key不可以为null

ConcurrentHashMap: 线程安全,使用synchronized锁加在每个链表上,锁冲突率低,充分利用CAS机制,优化了扩容方式,key不能为null.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【ARM Cortex-M 系列 1.1 -- Cortex-M33 与 M4 差异 详细介绍】

请阅读【嵌入式开发学习必备专栏 之 Cortex-Mx 专栏】 文章目录 背景Cortex-M33 与 M4 差异Cortex-M33Cortex-M4关系和差异举例说明 背景 在移植 RT-Thread 到 瑞萨RA4M2(Cortex-M33)上时,遇到了hardfault 问题,最后使用了Cortex…

路由器结构

路由器是连接互联网的设备,本文主要描述路由器的结构组成。 如上所示,OSI(Open System Interconnect)开放系统互联参考模型是互联网架构的标准协议栈,由ISO标准组织制定。自底向上,互联网架构分为7层&#…

行政快递管理软件使用教程

勤勤恳恳的行政人员,还在努力地修改企业快递管理制度,而聪明的行政人员,已经开始物色合适的快递管理软件了。随着企业管理的现代化发展,我们会发现很多管理模块都有相应的管理制度。人力资源管理、客户关系管理、财务管理等等&…

Unity animator动画倒放的方法

在Unity中, 我们有时候不仅需要animator正放的效果,也需要倒放的效果。但我们在实际制作动画的时候可以只制作一个正放的动画,然后通过代码控制倒放。 实现方法其实很简单,只需要把animator动画的speed设置为-1即为倒放&#xff…

MySQL中SELECT字句的顺序以及具体使用

目录 1.SELECT字句及其顺序 2.使用方法举例 3.HAVING和WHERE 1.SELECT字句及其顺序 *下表来自于图灵程序设计丛书,数据库系列——《SQL必知必会》 2.使用方法举例 *题目来源于牛客网 题目描述 现在运营想要查看不同大学的用户平均发帖情况,并期望结…

纯命令行在Ubuntu中安装qemu的ubuntu虚拟机,成功备忘

信息总体还算完整,有个别软件更新了名字,所以在这备忘一下 1. 验证kvm是否支持 ________________________________________________________________ $ grep vmx /proc/cpuinfo __________________________________________________________________…

【大数据】了解 YARN 架构的基础知识

了解 YARN 架构的基础知识 1.为什么是 YARN2.YARN 简介3.YARN 的组成部分3.1 Resource Manager 资源管理器3.1.1 Scheduler 调度程序3.1.2 Application Manager 应用程序管理器 3.2 Node Manager 节点管理器3.3 Application Master 应用程序主控3.4 Container 容器 4.在 YARN 中…

数据库课程设计-图书管理系统数据库设计

目录 一、实验目的 二、实验内容 三、实验要求 四、实验设计 4.1需求分析 4.1.1系统目标 4.1.2功能需求 4.1.3性能需求 4.14界面需求 4.2概念模型设计 4.2.1 实体及联系 4.2.2 E-R图 4.3 逻辑设计 4.3.1 E-R模型向关系模型的转换 4.3.2 数据库逻辑结构 4.3.3数据库模型函数依赖…

【leetcode】回溯总结

本文内容来自于代码随想录https://www.programmercarl.com/ 思想 一棵树中的纵向遍历结束回到上一层的过程,比如: 这个过程通常回伴随恢复现场的过程。 模板 void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择:本层集…

【实战】K8S部署Redis集群代理Predixy

文章目录 前言技术积累为什么要在redis集群前面加个predixy代理?这样做的好处有哪些?常用代理配置网络存储 实战构建predixy镜像并部署下载predixy源码编译构建镜像创建K8S配置文件predixy-configmap并执行网络储存PV与PVC部署predixy-deployment 测试代…

Go 日期时间包装器:15条更便捷的时间处理

★ 关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力! ” 在Go编程中,处理日期和时间是一项常见任务,涉及到精确性和灵活性。尽管Go的标准库提供了时间包&am…

为什么国产操作系统是基于linux研发的呢?

为什么国产操作系统是基于linux研发的呢? 在开始前我有一些资料,是我根据网友给的问题精心整理了一份「linux的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!&am…

Mysql详细安装步骤

Linux 安装 MySQL【超详细版】 ​编辑 我叫BuGu    2023-05-11 16:48:10 发布 一、安装 MySQL 的准备工作 1. 查看系统版本 cat /etc/redhat-release2. 查看系统是否已经安装过 MySQL 查看是否安装了 MySQL rpm -qa | grep mysql查看是否有安装 mariadb,该软件与 MySQ…

查看windows系统服务的日志

要查看Windows服务运行时产生的日志记录,请按照以下步骤操作: 1. **通过事件查看器查看服务日志:** - 按下 Win R 组合键打开“运行”对话框。 - 在“运行”对话框中输入 eventvwr.msc,然后按回车键或点击“确定”按钮以打…

力扣70. 爬楼梯(动态规划 Java,C++解法)

Problem: 70. 爬楼梯 文章目录 题目描述思路解题方法复杂度Code 题目描述 思路 由于本题目中第i层台阶只能由于第i- 1层台阶和第i-2层台阶走来,所以可以联想到动态规划,具体如下: 1.定义多阶段决策模型:对于每一上台阶看作一种状…

漏洞补丁修复之openssl版本从1.1.1q升级到1.1.1t以及python版本默认2.7.5升级到2.7.18新版本和Nginx版本升级到1.24.0

​ 一、Openssl升级 1、查看Openssl安装的版本 openssl version 2、查看Openssl路径 which openssl 3、上传openssl安装包到服务器:openssl-1.1.1t.tar.gz,并且解压,安装: mv /usr/local/openssl /usr/local/backup_openssl_1.1.1q_20240120 mkdir /usr/local/openssl tar…

【 Qt 快速上手】-①- Qt 背景介绍与发展前景

文章目录 1.1 什么是 Qt1.2 Qt 的发展史1.3 Qt 支持的平台1.4 Qt 版本1.5 Qt 的优点1.6 Qt的应用场景1.7 Qt的成功案例1.8 Qt的发展前景及就业分析行业发展方向就业方面的发展前景 1.1 什么是 Qt Qt 是一个跨平台的 C 图形用户界面应用程序框架。它为应用程序开发者提供了建立…

Web01--HTML基础

1、HTML 1.1 HTML概念 引用百度百科 HTML全称超文本标记语言(Hyper Text Markup Language),它不是一种编程语言,而是一种标记语言,通常用来制作网页。 超文本指的是页面上除了可以显示普通的文字以外,还可以显示图片、链接、甚…

一行代码就修复了Dubbo的Bug

1.什么是 System.identityHashCode? 2.什么是 hashCode? 3.为什么一行代码就修复了这个 BUG? 前情回顾 先通过一个前情回顾,引出本文所要分享的内容。 Dubbo 一致性哈希负载均衡算法的设计初衷应该是如果没有服务上下线的操作…

【C++入门到精通】智能指针 shared_ptr 简介及C++模拟实现 [ C++入门 ]

阅读导航 引言一、简介二、成员函数三、使用示例四、C模拟实现五、std::shared_ptr的线程安全问题六、总结温馨提示 引言 在 C 动态内存管理中,除了 auto_ptr 和 unique_ptr 之外,还有一种智能指针 shared_ptr,它可以让多个指针共享同一个动…