【JavaEE初阶】 线程安全的集合类

文章目录

  • 🍀前言
  • 🌲多线程环境使用 ArrayList
    • 🚩自己使用同步机制 (synchronized 或者 ReentrantLock)
    • 🚩Collections.synchronizedList(new ArrayList);
    • 🚩使用 CopyOnWriteArrayList
  • 🎍多线程环境使用队列
  • 🎋多线程环境使用哈希表
    • 🚩Hashtable
    • 🚩ConcurrentHashMap
  • 🌳相关面试题
  • ⭕总结

🍀前言

原来的集合类, 大部分都不是线程安全的.

Vector, Stack, HashTable, 是线程安全的(不建议用), 其他的集合类不是线程安全的.

为什么不建议使用呢?

因为我们在使用的时候,这些类就会自动的加锁,虽然编译器会自动优化为没有锁竞争的线程进行锁消除的优化,但是呢万一编译器没有优化好,就麻烦了

所以我们更多的是搭配一下其他方案达到线程安全,比如以下几种

🌲多线程环境使用 ArrayList

🚩自己使用同步机制 (synchronized 或者 ReentrantLock)

这里博主就不做过多赘述了,不懂得宝子可以去看一下博主对着方面的讲解

🚩Collections.synchronizedList(new ArrayList);

  • synchronizedList 是标准库提供的一个基于 synchronized 进行线程同步的List.

  • synchronizedList 的关键操作上都带有 synchronized

🚩使用 CopyOnWriteArrayList

使用CopyOnWrite容器即写时复制的容器

  • 当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,

  • 添加完元素之后,再将原容器的引用指向新的容器

这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。

所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

优点:

在读多写少的场景下, 性能很高, 不需要加锁竞争.

缺点:

  1. 占用内存较多.

  2. 新写的数据不能被第一时间读取到

🎍多线程环境使用队列

这个博主在讲【JavaEE初阶】 阻塞式队列详解中也有提到,所以这里只是简单列举

  1. ArrayBlockingQueue
    基于数组实现的阻塞队列

  2. LinkedBlockingQueue
    基于链表实现的阻塞队列

  3. PriorityBlockingQueue
    基于堆实现的带优先级的阻塞队列

  4. TransferQueue
    最多只包含一个元素的阻塞队列

🎋多线程环境使用哈希表

HashMap 本身不是线程安全的.

在多线程环境下使用哈希表可以使用:

  • Hashtable

  • ConcurrentHashMap

🚩Hashtable

Hashtable在实现过程中只是简单的把关键方法加上了 synchronized 关键字.
在这里插入图片描述
在这里插入图片描述

这相当于直接针对 Hashtable 对象本身加锁.

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

  • size 属性也是通过 synchronized 来控制同步, 也是比较慢的.

  • 一旦触发扩容, 就由该线程完成整个扩容过程. 这个过程会涉及到大量的元素拷贝, 效率会非常低
    在这里插入图片描述

🚩ConcurrentHashMap

相比于 Hashtable 做出了一系列的改进和优化. 以 Java1.8 为例

  • 读操作没有加锁(但是使用了 volatile 保证从内存读取结果), 只对写操作进行加锁. 加锁的方式仍然是是用 synchronized, 但是不是锁整个对象, 而是 “锁桶” (用每个链表的头结点作为锁对象), 大大降低了锁冲突的概率.

  • 充分利用 CAS 特性. 比如 size 属性通过 CAS 来更新. 避免出现重量级锁的情况.

优化了扩容方式: 化整为零

  • 发现需要扩容的线程, 只需要创建一个新的数组, 同时只搬几个元素过去.

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

  • 后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程. 每个操作负责搬运一小部分元素.

  • 搬完最后一个元素再把老数组删掉.

  • 这个期间, 插入只往新数组加.

  • 这个期间, 查找需要同时查新数组和老数组
    在这里插入图片描述
    想要详细了解的读者可以去ConcurrentHashMap源码分析(JDK8版本)进行查看

🌳相关面试题

  1. ConcurrentHashMap的读是否要加锁,为什么?

读操作没有加锁. 目的是为了进一步降低锁冲突的概率. 为了保证读到刚修改的数据, 搭配了 volatile 关键字.

  1. 介绍下 ConcurrentHashMap的锁分段技术?

这个是 Java1.7 中采取的技术. Java1.8 中已经不再使用了. 简单的说就是把若干个哈希桶分成一个 “段” (Segment),针对每个段分别加锁. 目的也是为了降低锁竞争的概率. 当两个线程访问的数据恰好在同一个段上的时候, 才触发锁竞争.

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

取消了分段锁, 直接给每个哈希桶(每个链表)分配了一个锁(就是以每个链表的头结点对象作为锁对 象). 将原来 数组 + 链表的实现方式改进成 数组 + 链表 / 红黑树 的方式. 当链表较长的时候(大于等于 8 个元素)就转换成红黑树.

  1. Hashtable和HashMap、ConcurrentHashMap 之间的区别?
  • HashMap: 线程不安全. key 允许为 null

  • Hashtable: 线程安全. 使用 synchronized 锁,Hashtable 对象, 效率较低. key 不允许为 null.

  • ConcurrentHashMap: 线程安全. 使用synchronized 锁每个链表头结点, 锁冲突概率低, 充分利用 CAS 机制. 优化了扩容方式. key 不允许为 null

⭕总结

关于《【JavaEE初阶】 线程安全的集合类》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!

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

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

相关文章

echarts-进度条

echarts-进度条 option {title: {text:"xxxx统计",left: 1%,top: 0%,textStyle: {color: "#2E3033",fontSize:18,},},tooltip: {axisPointer: {type: "shadow",},},grid: {top: 9%,left: "12%",right:"22%",bottom:"0…

react笔记基础部分(组件生命周期路由)

注意点&#xff1a; class是一个关键字&#xff0c; 类。 所以react 写class, 用classname &#xff0c;会自动编译替换class 点击方法&#xff1a; <button onClick {this.sendData}>给父元素传值</button>常用的插件&#xff1a; 需要引入才能使用的&#xf…

如何使用vim粘贴鼠标复制的内容

文章目录 一、使用步骤1.找到要编辑的配置文件2.找到目标文件3.再回到vim编辑器 一、使用步骤 1.找到要编辑的配置文件 用sudo vim /etc/apt/sources.list编辑软件源配置文件 sudo vim /etc/apt/sources.listvim 在默认的情况下当鼠标选中的时候进入的 Visual 模式&#xff…

GitLab升级16.5.0后访问提示502

系统是兼容CentOS8的TencentOS3.1 GitLab原来的版本是16.4.1 使用yum升级时发现GitLab有新版本,决定升级。 升级过程无异常,出现升级成功的提示。 可是意外的时,访问站点时提示502. GitLab比较吃资源,启动的服务较多。之前也有等会就正常的情况。 这次没那么幸运,一…

Go语言入门心法(十四): Go操作Redis实战

Go语言入门心法(一): 基础语法 Go语言入门心法(二): 结构体 Go语言入门心法(三): 接口 Go语言入门心法(四): 异常体系 Go语言入门心法(五): 函数 Go语言入门心法(六): HTTP面向客户端|服务端编程 Go语言入门心法(七): 并发与通道 Go语言入门心法(八): mysql驱动安装报错o…

【ARM Cortex-M 系列 4 番外篇 -- 常用 benchmark 介绍】

文章目录 1.1 CPU 性能测试 MIPS 计算1.1.1 Cortex-M7 CPI 1.2 benchmark 小节1.3.1 Geekbenck 介绍 1.3 编译参数配置 1.1 CPU 性能测试 MIPS 计算 每秒百万指令数 (MIPS)&#xff1a;在数据压缩测试中&#xff0c;MIPS 每秒测量一次 CPU 执行的低级指令的数量。越高越好&…

D71X-16Q手柄蝶阀型号解析

D71X-16Q型号字母含义解析 D71X-16Q是德特森阀门常用的手柄蝶阀型号字母分别代表的意思是: D——代表阀门类型《蝶阀》 7——代表连接方式《对夹》 1——代表结构形式《中线》 X——代表阀座材质《橡胶》 -代表分隔键 16——代表公称压力《1.6MPA》 Q——代表阀体材料《…

美创科技列为IDC中国数据安全市场代表厂商

近日&#xff0c;国际权威IT咨询机构IDC发布《中国数据安全市场发展趋势&#xff0c;2023》报告&#xff0c;报告针对中国数据安全市场的发展现状进行调研&#xff0c;明确了最终用户数据安全建设的痛点、难点&#xff0c;阐述了市场中各技术服务提供商的服务方案和优势。 美创…

如何恢复u盘删除文件?2023最新分享四种方法恢复文件

U盘上删除的文件怎么恢复&#xff1f;使用U盘存储文件是非常方便的&#xff0c;例如&#xff1a;在办公的时候&#xff0c;会使用U盘来存储网络上查找到的资料、产品说明等。在学习的时候&#xff0c;会使用U盘来存储教育机构分享的教学视频、重点知识等。而随着U盘存储文件的概…

css步骤条

html 代码以及样式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>css步骤条</title><style>.steps {display: flex;justify-content: space-between;padding: 0;margin: 20px 10px;lis…

数据结构笔记——树和图(王道408)(持续更新)

文章目录 传送门前言树&#xff08;重点&#xff09;树的数据结构定义性质 二叉树的数据结构定义性质储存结构 二叉树算法先中后序遍历层次展开法递归模拟法 层次遍历遍历序列逆向构造二叉树 线索二叉树&#xff08;难点&#xff09;定义线索化的本质 二叉树线索化线索二叉树中…

Elasticsearch分词器-中文分词器ik

文章目录 使用standard analysis对英文进行分词使用standard analysis对中文进行分词安装插件对中文进行友好分词-ik中文分词器下载安装和配置IK分词器使用ik_smart分词器使用ik_max_word分词器 借助Nginx实现ik分词器自定义分词网络新词 ES官方文档Text Analysis 使用standard…

react-typescript-demo

1.使用 Context 来存储数据

elasticSearch put全局更新和单个字段更新语法

1、如下&#xff1a;更新改类型未doc(文档)的全局字段数据 注意&#xff1a;如果你使用的是上面的语句&#xff0c;但是只写了id和title并赋值&#xff0c;图片上其他字段没有填写&#xff0c;执行命令后&#xff0c;则会把原文档中的其他字段都给删除了&#xff0c;你会发现查…

Linux虚拟网络设备—Veth Pair

veth是Virtual Ethernet Device的缩写&#xff0c;是一种成对出现的Linux虚拟网络接口设备。它最常用的功能是用于将不同的Linux network namespaces 命名空间网络连接起来&#xff0c;让二个namespaces之间可以进行通信。我们可以简单的把veth pair理解为用一根网线&#xff0…

ESB优势2019-架构师(六十二)

分布式数据数据库系统除了包含集中式数据库系统的模式结构外&#xff0c;还增加了几个模式级别&#xff0c;其中&#xff08;&#xff09;定义了分布式数据库中数据的整体逻辑结构、使得数据使用方便&#xff0c;如同没有分布一样。 分片模式全局外模式分布模式全局概念模式 …

VisualStudio[WPF/.NET]基于CommunityToolkit.Mvvm架构开发

一、创建 "WPF应用程序" 新项目 项目模板选择如下&#xff1a; 暂时随机填一个目标框架&#xff0c;待会改&#xff1a; 二、修改“目标框架” 双击“解决方案资源管理器”中<项目>CU-APP, 打开<项目工程文件>CU-APP.csproj, 修改目标框架TargetFramew…

企业出海:深入测评华为云云连接

随着全球化不断发展&#xff0c;中国企业也不断向海外拓展业务&#xff0c;然而出海企业面临不同以往的困难和挑战&#xff0c;在其中不可避免面临的跨境网络时延问题&#xff0c;如何选择区域进行部署企业业务&#xff0c;减少时延问题也成为需要重点考虑的问题。九河云结合测…

【嵌入式项目应用】__cJSON在单片机的使用

目录 前言 一、JSON和cJson 二、cJSON是如何表示JSON数据的 三、如何封装完整的JSON数据 1. 先将串口打通&#xff0c;方便电脑查看log日志。 2. 增加cjson.c文件&#xff0c;已经在main.c中 3. 准备打包如下的JSON包 4. 代码部分&#xff0c;先将几个部分初始化指针 …

web - Tomcat服务器

文章目录 目录 文章目录 前言 一 . CS和BS的异同 二 . 什么是Tomcat 二 . Tomcat安装 四 . Tomcat目录结构 bin目录: 用于存放二进制的可执行文件 config目录 server.xml&#xff1a;配置整个服务器信息。例如修改端口号。默认HTTP请求的端口号是&#xff1a;8080 lib目录 log…