Java EE 多线程之线程安全的集合类

文章目录

  • 1. 多线程环境使用 ArrayList
    • 1. 1 Collections.synchronizedList(new ArrayList)
    • 1.2 CopyOnWriteArrayList
  • 2. 多线程环境使用队列
    • 2.1 ArrayBlockingQueue
    • 2.2 LinkedBlockingQueue
    • 2.3 PriorityBlockingQueue
    • 2.4 TransferQueue
  • 3. 多线程环境使用哈希表
    • 3.1 Hashtable
    • 3.2 ConcurrentHashMap

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

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

针对这些线程不安全的集合类,要想在多线程环境下使用,就需要考虑好 线程安全问题了(加锁)

同时,标准库,也给我们提供了一些搭配的组件,保证线程安全

1. 多线程环境使用 ArrayList

1. 1 Collections.synchronizedList(new ArrayList)

Collections.synchronizedList(new ArrayList)
这个东西会返回一个新的对象,这个新的对象,就相当于给 ArrayList 套了一层外衣
这个外衣就是在方法上直接使用 synchronized 的

1.2 CopyOnWriteArrayList

CopyOnWriteArrayList 称为写实拷贝

比如,两个线程使用同一个 ArrayList ,可能会读,也可能会修改

如果要是两个线程读,可以直接进行读
如果某个线程需要进行修改,就把 ArrayList 复制出一份副本,修改这个副本
于此同时,另一个线程仍然可以读取书库(从原来的数据上进行读取)
一旦这边修改完毕,就会使用修改好的这份数据,替代掉原来的数据(往往就是一个引用赋值)

上述这个过程进行修改,就不需要加锁了


但是上述操作会存在一些问题

  1. 当前操作的 ArrayList 不能太大(拷贝成本,不能太高)
  2. 更适合于一个线程去修改,而不是多个线程同时修改(多个线程去,一个线程修改)

这种场景适合于 服务器的配置更新

可以通过配置文件,来描述配置的详细内容(本身不会很大)

配置的内容会被读到内存中,再由其他的线程,读取这里的内容
但是修改这个配置内容,往往只有一个线程来修改

如果程序员修改了配置文件,通过某种操作(使用命令)让服务器重新加载配置,就可使使用 写实拷贝 的方式

2. 多线程环境使用队列

2.1 ArrayBlockingQueue

基于数组实现的阻塞队列

2.2 LinkedBlockingQueue

基于链表实现的阻塞队列

2.3 PriorityBlockingQueue

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

2.4 TransferQueue

最多只包含⼀个元素的阻塞队列

3. 多线程环境使用哈希表

HashMap 本⾝不是线程安全的
在多线程环境下使⽤哈希表可以使⽤:
• Hashtable
• ConcurrentHashMap

3.1 Hashtable

Hashtable 保证线程安全,主要就是给关键方法,加上 synchronized
synchronized 是直接加到方法上的(相当于给 this 加锁)

只要两个线程,在同时操作同一个 Hashtable 就会出现锁冲突


但是实际上,对于哈希表来时,锁不一定非要这么加,有些情况,其实并不涉及到线程安全问题

两个不同的 key 映射到同一个数组下标上就会出现 hash 冲突
这个时候,我们可以使用链表来解决 hash 冲突
在这里插入图片描述
按照上述这样的方式,并且在不考虑触发扩容的前提下
操作不同的链表的时候就是线程安全的

相比之下,如果两个线程,操作的是同一个链表,会容易出现问题

如果两个线程,操作的是不同的链表,就根本不用加锁,只有说操作的是同一个链表才需要加锁

3.2 ConcurrentHashMap

ConcurrentHashMap 的改良方式:

  1. ConcurrentHashMap 相对比上述的HashMap,最核心的改进,就是把一个全局的大锁,改进成了 每个链表独立的一把小锁
    这样做大幅度降低了锁冲突的概率
    一个 hash 表,有很多这样的链表,两个线程恰好同时访问一个链表的情况,本身就比较少
  2. 充分利用到了 CAS 特性,把一些不必要加锁的环节给省略加锁了
    比如,需要使用变量记录 hash 表中的元素个数
    此时,就可以使用原子操作(CAS)修改元素个数
  3. ConcurrentHashMap 还有一个激进的操作,针对读操作没有加锁
    读和读之间,读和写之间,都不会有锁竞争
    那么是否会存在“读一半 修改了一半”的数值呢?
    ConcurrentHashMap 在底层编码过程中,比较谨慎的处理了一些细节
    修改的时候会避免使用 ++ – 这种非原子的操作
    使用 = 进行修改,本身就是原子的
    读的时候,要么读的就是写之前的旧值,要么是读到写之后的心智,不会出现读到一个 一半的值
    (写和写之间还是需要加锁的)
  4. ConcurrentHashMap 针对扩容操作,做出了单独的优化
    本身 Hashtable 或者 HashMap 在扩容的时候,都是需要把所有的元素都拷贝一遍(如果元素很多,拷贝就比较耗时)
    比如,用户访问 1000 次,999 次都很流畅,其中一次就卡了(正好这一次触发扩容,导致出现卡顿)
    ConcurrentHashMap 的优化方式就是“化整为零
    一旦需要扩容,确实需要搬运,不是在一次操作中搬运完成,而是分成多次 来搬运
    每次只搬运一部分数据,这样就可以避免这单次操作过于卡顿

ConcurrentHashMap 基本的使用方法和普通的 HashMap 完全一样

在第一点中,我们是怎么把每个链表单独加锁的呢?
其实就是把每个链表的头结点,作为锁对象
synchronized 可以使用任意对象作为锁对象

在这个时候,我们有的时候会提到分段锁
什么是分段锁呢?
在 java 8 之前, ConcurrentHashMap 就是基于分段锁的方式实现的
等到 java 8 开始之后,就成了直接在链表头结点,加锁的形式

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

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

相关文章

innerHTML、innerText、textContent有什么区别

innerHTML、innerText、textContent有什么区别 在 HTML 中,innerHTML、innerText、 和textContent是 DOM(文档对象模型)的属性。它们允许我们读取和更新 HTML 元素的内容。 但它们在包含的内容以及处理 HTML 标签的方式有不同的行为。 读完…

分布式事务seata使用示例及注意事项

分布式事务seata使用示例及注意事项 示例说明代码调用方(微服务A)服务方(微服务B) 测试测试一 ,seata发挥作用,成功回滚!测试二:处理feignclient接口的返回类型从Integer变成String,…

【Spring Boot】快速入门

一、引言 1、什么是spring boot? Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式&#xff…

【RocketMQ-Install】Windows 环境下安装 RocketMQ 及基础命令的使用

【RocketMQ-Install】Windows 环境下 安装本地 RocketMQ 及基础命令的使用 1)下载 RocketMQ 安装包1.1.官网下载(推荐)1.2.Git 下载1.3.安装环境要求说明 2)Windows 安装3)基础命令测试 1)下载 RocketMQ 安…

多分类预测 | MATLAB实现CNN-LSTM-Attention多输入分类预测

分类预测 | MATLAB实现CNN-LSTM-Attention多输入分类预测 分类效果 需要源码和数据的私信(微微有偿取哦)

通义千问 Qwen-72B-Chat在PAI-DSW的微调推理实践

01 引言 通义千问-72B(Qwen-72B)是阿里云研发的通义千问大模型系列的720亿参数规模模型。Qwen-72B的预训练数据类型多样、覆盖广泛,包括大量网络文本、专业书籍、代码等。Qwen-72B-Chat是在Qwen-72B的基础上,使用对齐机制打造的…

主宰无双H5:WIN学习手工服务端通用视频教程及GM授权物品后台,支持三网H5玩法介绍

标题:主宰无双H5(游戏源码):WIN学习手工服务端通用视频教程及GM授权物品后台,支持三网H5玩法的百科 一、引言 随着互联网的快速发展,H5游戏逐渐成为人们休闲娱乐的重要方式。主宰无双H5游戏源码作为一款深…

Android解决报错 superclass access check failed: class

Android解决报错 superclass access check failed: class 前言: 最近在打开之前的项目demo时,出现一个错误Cause: superclass access check failed: class butterknife.compiler.ButterKnifeProcessor$RScanner 1.错误信息如下: Executio…

《Linux C编程实战》笔记:目录操作

目录的创建和删除 mkdir函数 #include <sys/stat.h> #include <sys/types.h> int mkdir(const char *pathname, mode_t mode); mkdir创建一个新的空目录。空目录中会自动创建.和..目录项。所创建的目录的存取许可权由mode (mode &~umask)指定。 新创建目录的…

[Linux] LVS负载均衡群集+NAT部署

一、LVS负载均衡群集知识 1.1 群集的的定义及意义 Cluster&#xff0c;集群&#xff08;也称群集&#xff09;由多台主机构成&#xff0c;但对外只表现为一一个整体&#xff0c;只提供一-个访问入口(域名或IP地址)&#xff0c; 相当于一台大型计算机。 群集的作用&#xff1…

vue3使用Mars3D写区块地图

效果图 引入相关文件 因为我也是第一次使用&#xff0c;所以我是把插件和源文件都引入了&#xff0c;能使用启动 源文件 下载地址&#xff1a; http://mars3d.cn/download.html 放入位置 在index.html中引入 <!--引入cesium基础lib--><link href"/static/C…

Kubernetes 容器编排 -- 1

前言 知识扩展 早在 2015 年 5 月&#xff0c;Kubernetes 在 Google 上的搜索热度就已经超过了 Mesos 和 Docker Swarm&#xff0c;从那儿之后更是一路飙升&#xff0c;将对手甩开了十几条街,容器编排引擎领域的三足鼎立时代结束。 目前&#xff0c;AWS、Azure、Google、阿里…

软考科目如何选择?

软考科目繁多&#xff0c;让许多学弟学妹感到困惑&#xff0c;不知道该选择哪个科目。以下是一些建议&#xff0c;可以根据个人实际需求选择备考的科目。 1、初级是可选的 软考初级非常简单&#xff0c;适合刚刚入门学习的朋友报考。对于一些有基础的朋友&#xff0c;建议直接…

【从零开始学习--设计模式--装饰者模式】

返回首页 前言 感谢各位同学的关注与支持&#xff0c;我会一直更新此专题&#xff0c;竭尽所能整理出更为详细的内容分享给大家&#xff0c;但碍于时间及精力有限&#xff0c;代码分享较少&#xff0c;后续会把所有代码示例整理到github&#xff0c;敬请期待。 此章节介绍装…

java实现局域网内视频投屏播放(二)爬虫

代码链接 视频播放原理 大多视频网站使用的是m3u8&#xff0c;m3u8其实不是一个真正的视频文件&#xff0c;而是一个视频播放列表&#xff08;playlist&#xff09;。它是一种文本文件&#xff0c;里面记录了一系列的视频片段&#xff08;segment&#xff09;的网络地址。这些…

原来定时发朋友圈设置这么简单?看完我也会了

目前微信作为最大的社交平台之一&#xff0c;吸引了众多使用者。你是否听过有些朋友感叹这么多微信号&#xff0c;需要每天手动发布朋友圈&#xff0c;任务很繁琐呢&#xff1f;是否希望可以事先设置好定时发送的功能&#xff0c;让朋友圈自动更新&#xff0c;省去手动发送的麻…

初探栈溢出(下)

0x04 漏洞利用 作为脚本小子&#xff0c;先跑一下写好了的exploit脚本。 打开HackSysEVDExploit.sln文件&#xff0c;直接在vs2019上编译即可。 将生成的HackSysEVDExploit.exe拷贝至win7&#xff0c;执行如下命令 直接可以获取system权限。 那么只跑一下脚本肯定不行&#…

世微 锂电池保护IC DW01 充电器检测过充保护SOT23-6

一、 描述 DW01A 是一个锂电池保护电路&#xff0c;为避免锂电池因过充电、过放电、电流过大导致电池寿命缩短或电池被损坏而设计的。它具有高精确度的电压检测与时间延迟电路。 二、 主要特点 工作电流低 过充检测 4.3V&#xff0c;过充释放 4.05V&#xff1b; 过放检测 2.4…

黑马头条--day01.环境搭建

一.前言 该项目学习自黑马程序员&#xff0c;由我整理如下&#xff0c;版权归黑马程序员所有 二.环境搭建 1.数据库 第一天&#xff0c;先创建如下库和表: sql文件如下: CREATE DATABASE IF NOT EXISTS leadnews_user DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_…

LeetCode(62)删除排序链表中的重复元素 II【链表】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 删除排序链表中的重复元素 II 1.题目 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1…