JavaEE(系列17) -- 线程安全的集合类

news2024/12/26 12:03:47

目录

1. 多线程环境使用ArrayList

1.1 使用同步机制 (synchronized 或者 ReentrantLock)

1.2 Collections.synchronizedList(new ArrayList);

1.3 使用 CopyOnWriteArrayList 

2. 多线程环境使用队列

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

3.1 Hashtable 

3.2 ConcurrentHashMap

4. 相关面试题 

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

4.2 介绍下 ConcurrentHashMap的锁分段技术?

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

4.4 Hashtable和HashMap、ConcurrentHashMap 之间的区别?


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


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

1. 多线程环境使用ArrayList

1.1 使用同步机制 (synchronized 或者 ReentrantLock)

1.2 Collections.synchronizedList(new ArrayList);

synchronizedList 是标准库提供的一个基于 synchronized 进行线程同步的 List.
synchronizedList 的关键操作上都带有 synchronized

1.3  使用 CopyOnWriteArrayList 

 CopyOnWrite容器即写时复制的容器

  • 当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素
  • 添加完元素之后,再将原容器的引用指向新的容器.

这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。
所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。 

 

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


缺点:
1. 占用内存较多.
2. 新写的数据不能被第一时间读取到.

2. 多线程环境使用队列

  • 1) ArrayBlockingQueue:基于数组实现的阻塞队列
  • 2) LinkedBlockingQueue:基于链表实现的阻塞队列
  • 3) PriorityBlockingQueue:基于堆实现的带优先级的阻塞队列
  • 4) TransferQueue:最多只包含一个元素的阻塞队列

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

HashMap 本身不是线程安全的.
在多线程环境下使用哈希表可以使用:

  • Hashtable
  • ConcurrentHashMap

3.1 Hashtable 

只是简单的把关键方法加上了 synchronized 关键字.

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


        如果多线程访问同一个 Hashtable 就会直接造成锁冲突.size 属性也是通过 synchronized 来控制同步, 也是比较慢的.一旦触发扩容, 就由该线程完成整个扩容过程. 这个过程会涉及到大量的元素拷贝, 效率会非常低.

 当线程修改不同下标的链表的时候,本来是线程安全的,但是也要进行等待锁,这样就不太合理.

3.2 ConcurrentHashMap

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

  • 读操作没有加锁(但是使用了 volatile 保证从内存读取结果), 只对写操作进行加锁. 加锁的方式仍然是是用 synchronized, 但是不是锁整个对象, 而是 "锁桶" (用每个链表的头结点作为锁对象), 大大降低了锁冲突的概率.
  • 充分利用 CAS 特性. 比如 size 属性通过 CAS 来更新. 避免出现重量级锁的情况.
  • 优化了扩容方式: 化整为零(分很多次进行将原来的元素进行搬家)
  1.         发现需要扩容的线程, 只需要创建一个新的数组, 同时只搬几个元素过去.
  2.         扩容期间, 新老数组同时存在.
  3.         后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程. 每个操作负责搬运一小部分元素.
  4.         搬完最后一个元素再把老数组删掉.
  5.         这个期间, 插入只往新数组加.
  6.         这个期间, 查找需要同时查新数组和老数组 

 

 

4. 相关面试题 

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

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

4.2 介绍下 ConcurrentHashMap的锁分段技术?

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

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

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

4.4 Hashtable和HashMap、ConcurrentHashMap 之间的区别?

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

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

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

相关文章

北邮22信通:利用BF算法解决实际问题:题目实战(超详解)设计函数 char *locatesubstr(char *str1,char *str2)

北邮22信通一枚~ 跟随课程进度每周更新数据结构与算法的代码和文章 持续关注作者 解锁更多邮苑信通专属代码~ 获取更多文章 请访问专栏~ 北邮22信通_青山如墨雨如画的博客-CSDN博客 目录 题干描述 解析 1.string库函数 2.使用KMP算法思想 注解1 注解2 注解3 题…

Mysql基础 — DDL、DML、DQL、DCL、函数、约束

文章目录 Mysql基础一、数据模型1.1 关系型数据库与非关系型数据库1.2 Mysql 数据模型 二、SQL2.1 SQL 通用语法2.2 SQL分类2.3 DDL2.3.1 数据库操作2.3.2 表操作 — 创建 & 查询2.3.3 表操作— 修改&删除2.3.4 数据类型2.3.4.1 数值类型2.3.4.2 字符串类型2.3.4.3 日期…

LabImg安装与使用

一、LabImg安装 安装命令语句 pip install labelimg 或 conda install labelimg 后者,可以有效避免依赖库缺失情况。一般,第一个命令语句无法安装时,可以尝试用第二个命令语句。 示例 以管理员身份打开命令提示符窗口,输入…

js的堆栈和垃圾回收机制(gc)

js的堆栈和垃圾回收机制(gc) 本文目录 js的堆栈和垃圾回收机制(gc)堆栈深拷贝和浅拷贝实现深拷贝 垃圾回收机制栈溢出概念垃圾产生算法策略V8引擎的优化新生代:Scavenge 算法老生代:标记-清除-整理 算法 堆…

厚积薄发丨美格智能子公司众格智能荣获“张江之星”“闵行区企业技术中心”双项企业授牌

5月23日下午,2023年闵行科技节开幕式在大零号湾科创大厦举行。在开幕式“创蝶变智造”板块,美格智能技术股份有限公司全资子公司众格智能科技(上海)有限公司(以下简称:众格智能)入选“张江之星”…

加速数实融合,数据交易3.0模式上新

数据交易市场将迎来真正的突破? 目前看的确如此。随着去年底“数据二十条”的颁布,业界普遍认为数据基础制度将加速走向落地与完善,数据要素化今年有望迎来全面提速,将极大促进数据交易市场走向规模化。 IDC预测,到2…

QMI8658 - 姿态传感器学习笔记 - Ⅲ

文章目录 1.复位1.1 上电复位:1.2 推荐工作条件 2. 校准(COD)2.1 校准步骤2.2 校准注意事项:2.3 校准状态指示2.4 校准参数更新 3. 自检3.1 加速度计自检3.2 陀螺仪自检 4. Ctrl94.1 写Ctrl94.2 读Ctrl94.3 Ctrl9详细命令说明 5. 中断5.1 同步采样模式5.…

直接缓存访问DCA

直接缓存访问DCA:网卡原本DMA写是将接收到的数据帧写入系统内存,DCA机制是网卡DMA写输入的数据能直接发送到属于CPU内部的L2高速缓存中,从而提高网络IO的性能。 设备驱动程序要初始化网卡的DCA功能,将CPU ID号(通过获取…

CentOS安装Whisper | RedHat安装Whisper | 服务器上安装Whisper

1、升级Python版本(可选) CentOS 7.9 系统默认安装的Python版本有两个,如果输入python -V我们看到的是python2的版本信息,如果我们输入python3 -V我们看到的是python3的版本信息。 由于whisper要求使用的是python版本是在3.8到3…

Linux(Ubuntu)安装和使用Edge浏览器

全文内容完全由AI创作,并通过人工核验,感谢各位的阅读。 Microsoft Edge是一款现代化的浏览器,它拥有众多功能和强大的性能,为用户带来更加流畅的浏览体验。 Edge最近推出了分屏功能,支持一个窗口同时显示两个选项卡&…

MySQL基础 — 多表查询以及事务管理

文章目录 MySQL基础 — 多表查询以及事务管理一、多表查询1.1 对应关系1.2 准备数据1.3 概述1.4 内连接1.5 外连接1.6 自连接1.7 联合查询 union1.8 子查询1.8.1 标量子查询1.8.2 列子查询1.8.3 行子查询1.8.4 表子查询 二、事务2.1 简介2.2 操作演示2.3 控制事务2.3.1 控制事务…

深入浅出Vite:深入理解 Rollup 的插件机制

上一节我们学会了 Rollup 构建工具的使用,相信你已经对 Rollup 的基础概念和使用有了基本的掌握。同时我们也知道,仅仅使用 Rollup 内置的打包能力很难满足项目日益复杂的构建需求。对于一个真实的项目构建场景来说,我们还需要考虑到模块打包…

如何通过CRM系统做好客户的分级分类

随着市场竞争的不断加剧,尤其是以客户为中心时代的到来,企业越来越注重客户的管理和服务。而CRM系统,作为企业客户管理的重要工具,其核心任务是对客户进行分级分类,以便更好地为客户提供定制化的服务。 客户之间的价值…

在 Docker 容器中安装 nvm

目录 前言一、步骤1.下载nvm安装脚本2.激活nvm3.安装Node.js4.验证 Node.js 是否安装成功5.如果需要安装特定版本的 Node.js,可以使用以下命令6.如果需要使用特定版本的 Node.js,可以使用以下命令6.验证特定版本的 Node.js 是否安装成功 总结 前言 提示…

关于 arduino 中的 random()和randomSeed()的使用

0、random() 函数: 用于生成一个指定范围内的伪随机整数,可以使用该函数在程序中产生不同的随机数。其语法如下: random(min, max) 其中,min 表示随机数的最小值,max 表示随机数的最大值(不包括该…

介绍几种常见的运维发布策略

随着Devops的发展,为了提高运维发布的成功率,探索出了多种发布策略。本文简单介绍几种常见发布策略, 以及它们适用的场景和优缺点。 第一种,停机发布 这是最早的一种发布策略,停机发布会在发布以前关闭服务,停止用户…

benders分解算法 逻辑思路整理(加星)

Benders decomposition 目录 1.benders的分类 2. 经典的benders分解 2.1 经典的benders分解注意点 2.2 benders分解的核心——子问题和对偶子问题的分析 benders分解本质是: (1)将问题分解为松弛主问题和子问题 (2&#xff0…

支付宝SDK接口调试- cpolar内网穿透工具实现公网地址调试(1)

文章目录 1.测试环境2.本地配置3. 内网穿透3.1 下载安装cpolar内网穿透3.2 创建隧道 4. 测试公网访问5. 配置固定二级子域名5.1 保留一个二级子域名5.2 配置二级子域名 6. 使用固定二级子域名进行访问 转发自cpolar内网穿透的文章:Java支付宝沙箱环境支付&#xff0…

Cisco Identity Services Engine (ISE) 3.2 Patch2 发布 - 思科身份服务引擎

Cisco Identity Services Engine (ISE) 3.2 Patch2 发布 - 思科身份服务引擎 请访问原文链接:https://sysin.org/blog/cisco-ise-3/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org 工作场所零信任安全的核心所在 …

FL Studio水果软件好用吗?对电脑硬件环境有哪些需求

如果你打算将来朝着艺术和音乐方向发展,那么学习音乐理论和音乐制作就是一门基础课了。 实践才是检验学习效果途径,在我们日常的练习中,一款功能强大且易学的音乐制作工具是少不了的。在没有实际体验过各个音乐制作工具的功能前,…