当前位置: 首页 > news >正文

[JAVAEE] 面试题(四) - 多线程下使用ArrayList涉及到的线程安全问题及解决

目录

一. 多线程下使用ArrayList

1.1. 自行判断加锁

1.2 使用Collections.synchronizedList()套壳加锁

1.3 CopyOnWriteArrayList类

二. 总结


一. 多线程下使用ArrayList

多线程下使用ArrayList会涉及到线程安全问题, 例如:

    public static void main(String[] args) throws InterruptedException{List<Integer> list = new ArrayList<>();Runnable runnable = () -> {for (int i = 0; i < 50000; i++) {list.add(i);}};// 创建两个线程for (int i = 0; i < 2; i++) {new Thread(runnable).start();}Thread.sleep(5000);System.out.println(list.size());}

可以发现, 最后的结果并不是期待的100000, 这是因为ArrayList中的add方法并没有处理线程安全问题.

那么, 如何解决在多线程场景下使用ArrayList产生的线程安全问题呢? 如下, 有三种解决方案.

1.1. 自行判断加锁

就是根据需要来进行加锁, 将一些可能会产生线程安全问题的操作通过加锁打包成为原子操作.

        Runnable runnable = () -> {for (int i = 0; i < 50000; i++) {synchronized (locker) {list.add(i);}}};

结果正如我们所期待的那样.

1.2 使用Collections.synchronizedList()套壳加锁

对读操作和写操作全部都加锁, 保证线程安全. (此时返回的List对象中的重要操作都加锁了)

但是会降低程序运行效率, 因为读操作本身不会产生线程安全问题, 又加锁就是多此一举了!!!

我们来看看synchronizedList类中add方法是怎么实现的, 

        public void add(int index, E element) {synchronized (mutex) {list.add(index, element);}}

此时, 结果也是正确的.

1.3 CopyOnWriteArrayList类

CopyOnWrite 写时拷贝, 实现了读与读不互斥, 读与写不互斥, 写与写互斥. 保证了线程安全.

那么, 是怎么实现读与写不互斥的呢?

在面临写操作的时候, 会依照旧数组复制一个新数组, 修改操作就在新数组上进行, 最后再将旧数组覆盖.如果在写操作的时候发生了线程切换, 并且切换到了读操作, 此时还是会读取旧数组. 保证了线程安全.

 CopyOnWriteArrayList类中add方法的实现:

        /*** Appends the specified element to the end of this list.** @param e element to be appended to this list* @return {@code true} (as specified by {@link Collection#add})*/public boolean add(E e) {synchronized (lock) {Object[] es = getArray();int len = es.length;es = Arrays.copyOf(es, len + 1);es[len] = e;setArray(es);return true;}}

结果也是正确的.


二. 总结

1. 多线程下使用ArrayList类, 涉及到了线程安全问题, 以及解决线程安全问题的方法.

2. 自行判断加锁. 效率高

3. Collections.synchronizedList()套壳封装, 效率低下. 因为对不涉及线程安全问题的操作进行加锁.(即对List接口中的所有方法进行加锁)

4. CopyOnWriteArrayList类, 写时拷贝. 实现了读与读, 读与写操作不互斥, 写与写操作互斥. 保证了线程安全, 并且效率相对高效.

相关文章:

[JAVAEE] 面试题(四) - 多线程下使用ArrayList涉及到的线程安全问题及解决

目录 一. 多线程下使用ArrayList 1.1. 自行判断加锁 1.2 使用Collections.synchronizedList()套壳加锁 1.3 CopyOnWriteArrayList类 二. 总结 一. 多线程下使用ArrayList 多线程下使用ArrayList会涉及到线程安全问题, 例如: public static void main(String[] args) thro…...

Elasticsearch-linux环境部署

本文主要介绍linux下elasticsearch的部署。通过在一台linux服务器中分别对elasticsearch-6.7.2版本&#xff0c;elasticsearch-7.3.0版本来进行安装&#xff0c;记录在安装elasticsearch-7.3.0版本时出现的异常情况&#xff0c;以及elasticsearch-head的安装。 基础环境 本机已…...

LeetCode 每日一题 长度为 K 的子数组的能量值

长度为 K 的子数组的能量值 给你一个长度为 n 的整数数组 nums 和一个正整数 k 。 一个数组的 能量值 定义为&#xff1a; 如果 所有 元素都是依次 连续 且 上升 的&#xff0c;那么能量值为 最大 的元素。 否则为 -1 。 你需要求出 nums 中所有长度为 k 的 子数组 的能量值。 …...

人工智能——小白学习指南

知孤云出岫 目录 1. **智能评测系统**2. **个性化学习路径推荐**3. **虚拟学习助手**4. **学习行为分析**5. **数据驱动的教学决策**6. **自动化课程推荐**7. **数据隐私与安全保护** 人工智能知识点的总结和学习路线&#xff0c;以数据表格形式呈现&#xff0c;并附带在教育行…...

go 集成Gin Web开发框架

引入gin的依赖 下载并安装 gin go get -u github.com/gin-gonic/gin 将 gin 引入到代码中 import "github.com/gin-gonic/gin" 开始 package mainimport "github.com/gin-gonic/gin"func main() {r : gin.Default()r.GET("/ping", func(c …...

c++ 多态性

类的多态 多态概念入门 #include <iostream> using namespace std;/* 多态的前提: 拥有继承关系的类中有相同的函数(返回类型、函数名、形参列表) 多态解决的问题&#xff1a;1、派生类的对象被赋值给基类对象时2、派生类的对象初始化基类的引用时3、基类的指针指向派生…...

块存储、文件存储和对象存储详细介绍

块存储、文件存储和对象存储介绍 块存储&#xff1a;像跑车&#xff0c;因为它们都能提供快速的响应和高性能&#xff0c;适合需要即时数据访问的场景&#xff0c;比如数据库和虚拟化技术。 文件存储&#xff1a;像货车&#xff0c;因为它们都能承载大量货物&#xff08;文件&…...

移植 AWTK 到 纯血鸿蒙 (HarmonyOS NEXT) 系统 (9) - 编译现有的AWTK应用程序

AWTK 应用程序开发完成后&#xff0c;在配置文件中添加 harmonyos 的选项&#xff0c;通过create_project.py脚本即可生成 DevEco Studio的工程。 安装开发环境 DevEco Studio HarmonyOS 的开发工具。 Python 运行环境。 git 源码管理工具。 下载 awtk 和 awtk-harmonyos…...

ssm基于BS的仓库在线管理系统的设计与实现+vue

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码看文章最下面 需要定制看文章最下面 目 录 第一章 绪论 1 1.1 研究背景 1 1.2 研究意义 1 1.3 研究内容 2 第二章 开发环境与技术3 …...

面试题:Spring(一)

1. Spring框架中bean是单例么&#xff1f; Service Scope("singleton") public class UserServiceImpl implements UserService { }singleton : bean在每个Spring IOC容器中只有一个实例。prototype&#xff1a;一个bean的定义可以有多个实例。 2. Spring框架中的…...

MySQ怎么使用语法介绍(详细)

一、什么是库结构 库结构的意思就是指数据库的结构。所以&#xff0c;理解“库结构”就要先理解“库”是什么。 在数据库的上下文中&#xff0c;库指的是一个数据库。简单来说&#xff0c;数据库&#xff08;库&#xff09;是用来存储和管理数据的容器。它不仅存储实际的数据…...

新能源汽车与公共充电桩布局

近年来,全球范围内对新能源汽车产业的推动力度不断增强,中国新能源汽车市场也呈现蓬勃发展的势头,在政策与市场的共同推动下,新能源汽车销量持续增长。然而,据中国充电联盟数据显示,充电基础设施建设滞后于新能源汽车数量增长的现状导致充电桩供需不平衡,公共充电桩服务空白区域…...

【GIT】sourceTree的“当前分支“,“合并分支“与“检出分支的区别

GIT三款经典可视化 由上文文档得出灵感写出此篇 这三个概念在 Git 操作中都是很常见的&#xff0c; 来逐个解析&#xff1a; 1. 当前分支 “当前分支”就是你目前正在工作的分支。你在进行任何代码修改、提交等操作时&#xff0c;都会应用到“当前分支”上。换句话说&#xf…...

【Git】如何在 Git 中高效合并分支:完整指南

目录 引言1. 切换到主分支1.1 切换分支命令1.2 相关命令1.3 切换分支示意图 2. 合并分支2.1 基本合并命令2.2 合并选项2.3 合并流程示意图 3. 解决冲突3.1 解决冲突的步骤3.2 相关命令3.3 解决冲突示意图 4. 本地更新分支4.1 拉取远程更改4.2 更新主分支4.3 拉取远程更新到本地…...

成都睿明智科技有限公司抖音电商服务效果如何?

在这个短视频风起云涌的时代&#xff0c;抖音电商以其独特的魅力&#xff0c;成为了众多商家竞相追逐的新蓝海。而在这片波澜壮阔的商海中&#xff0c;成都睿明智科技有限公司犹如一艘稳健的航船&#xff0c;引领着无数企业驶向成功的彼岸。今天&#xff0c;就让我们一起揭开成…...

收集的linux命令/Docker命令/git命令

查看linux发行版本 lsb_release -a显示操作系统的发行版号 uname -r1. 启动 Docker。 sudo systemctl start docker2. 通过运行映像来验证 Docker 引擎安装是否成功。hello-world sudo docker run hello-world查看docker版本 docker -v查看docker配置信息 docker infodoc…...

DNS域名解析实验

准备工作 [rootlocalhost ~]# setenforce 0 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# mount /dev/sr0 /mnt [rootlocalhost ~]# dnf install bind -y DNS正向解析&#xff1a; 对主配置文件进行修改 [rootlocalhost ~]# vim /etc/named.conf 正向解析…...

Dify 本地部署指南

一、前置条件 Clone Dify 代码&#xff1a; git clone https://github.com/langgenius/dify.git 在启用业务服务之前&#xff0c;我们需要先部署 PostgresSQL / Redis / Weaviate&#xff08;如果本地没有的话&#xff09;&#xff0c;可以通过以下命令启动&#xff1a; cd…...

15分钟学 Go 第 38 天:数据库基础

第38天 - 数据库基础 学习目标 学习如何连接和操作数据库&#xff0c;包括基本的增、删、改、查功能&#xff0c;以及如何使用Go语言中的database/sql包进行数据库交互。 内容概述 在现代应用程序中&#xff0c;数据库是数据持久化的重要部分。Go语言通过database/sql包提供…...

【Python】图片处理

一、获取图片尺寸 优点缺点Pillow功能丰富&#xff0c;支持多种图像处理操作。使用简单&#xff0c;适合快速原型开发。对于处理大型图像或批量图像时&#xff0c;性能可能不如OpenCV。OpenCV性能强大&#xff0c;适合处理大型图像和视频处理。提供了丰富的计算机视觉算法。相…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

rknn toolkit2搭建和推理

安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 &#xff0c;不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源&#xff08;最常用&#xff09; conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”

案例&#xff1a; 某医药分销企业&#xff0c;主要经营各类药品的批发与零售。由于药品的特殊性&#xff0c;效期管理至关重要&#xff0c;但该企业一直面临效期问题的困扰。在未使用WMS系统之前&#xff0c;其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...