并发工具类库使用的常见问题
一、ThreadLocal在多线程环境中没有清理
由于ThreadLocal是和线程绑定的,如果线程被复用了,也即使用了线程池,那么ThreadLocal中的值是可能被复用的,这个特性如果是开发者没有预料到的,那么会产生很大的问题。例如,在JAVA web应用中,我们通常会使用很多ThreadLocal来保存一次请求的不同上下文信息,其中就包含登录用户,如果一次请求完成后,没有清理掉当前登录用户信息,那么当另外一个用户的请求进来,就会使用上一个用户,如果是涉及到数据写入,将直接导致数据错乱,造成严重生产问题。
二、ConcurrentHashMap使用的问题
ConcurrentHashMap提供的能力是保证单个操作在多线程环境下是安全的。如果有一段逻辑是先读取size大小,在决定是否往map里put(),那么这段逻辑必然产生并发问题。因为错误理解的ConcurrentHashMap的能力。解决办法是用加锁的方式控制并发。
三、CopyOnWriteArrayList使用的问题
CopyOnWrite 是一个常用的技术,Linux、Redis中都用到了。在 Java 中,CopyOnWriteArrayList 虽然是一个线程安全的 ArrayList,但因为其实现方式是,每次修改数据时都会复制一份数据出来,所以有明显的适用场景,即读多写少或者说希望无锁读的场景。
//测试并发写的性能
@GetMapping("write")
public Map testWrite() {
List<Integer> copyOnWriteArrayList = new CopyOnWriteArrayList<>();
List<Integer> synchronizedList = Collections.synchronizedList(new ArrayList<>());
StopWatch stopWatch = new StopWatch();
int loopCount = 100000;
stopWatch.start("Write:copyOnWriteArrayList");
//循环100000次并发往CopyOnWriteArrayList写入随机元素
IntStream.rangeClosed(1, loopCount).parallel().forEach(__ -> copyOnWriteArrayList.add(ThreadLocalRandom.current().nextInt(loopCount)));
stopWatch.stop();
stopWatch.start("Write:synchronizedList");
//循环100000次并发往加锁的ArrayList写入随机元素
IntStream.rangeClosed(1, loopCount).parallel().forEach(__ -> synchronizedList.add(ThreadLocalRandom.current().nextInt(loopCount)));
stopWatch.stop();
log.info(stopWatch.prettyPrint());
Map result = new HashMap();
result.put("copyOnWriteArrayList", copyOnWriteArrayList.size());
result.put("synchronizedList", synchronizedList.size());
return result;
}//帮助方法用来填充List
private void addAll(List<Integer> list) {
list.addAll(IntStream.rangeClosed(1, 1000000).boxed().collect(Collectors.toList()));
}//测试并发读的性能
@GetMapping("read")
public Map testRead() {
//创建两个测试对象
List<Integer> copyOnWriteArrayList = new CopyOnWriteArrayList<>();
List<Integer> synchronizedList = Collections.synchronizedList(new ArrayList<>());
//填充数据
addAll(copyOnWriteArrayList);
addAll(synchronizedList);
StopWatch stopWatch = new StopWatch();
int loopCount = 1000000;
int count = copyOnWriteArrayList.size();
stopWatch.start("Read:copyOnWriteArrayList");
//循环1000000次并发从CopyOnWriteArrayList随机查询元素
IntStream.rangeClosed(1, loopCount).parallel().forEach(__ -> copyOnWriteArrayList.get(ThreadLocalRandom.current().nextInt(count)));
stopWatch.stop();
stopWatch.start("Read:synchronizedList");
//循环1000000次并发从加锁的ArrayList随机查询元素
IntStream.range(0, loopCount).parallel().forEach(__ -> synchronizedList.get(ThreadLocalRandom.current().nextInt(count)));
stopWatch.stop();
log.info(stopWatch.prettyPrint());
Map result = new HashMap();
result.put("copyOnWriteArrayList", copyOnWriteArrayList.size());
result.put("synchronizedList", synchronizedList.size());
return result;
}
相关文章:
并发工具类库使用的常见问题
一、ThreadLocal在多线程环境中没有清理 由于ThreadLocal是和线程绑定的,如果线程被复用了,也即使用了线程池,那么ThreadLocal中的值是可能被复用的,这个特性如果是开发者没有预料到的,那么会产生很大的问题。例如&am…...
GD32F10X ----RTC
1. RTC的简介 STM32 的实时时钟(RTC)是一个独立的定时器。STM32 的 RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。 RTC 模块和时钟配置…...
使用UiPath和AA构建的解决方案 1. 机器人过程自动化入门
你好!在这本系列,我们将指导您完成一些真实世界的机器人过程自动化(RPA)项目。感谢您的加入。当你完成本系列时,你将具备使用UiPath和Automation Anywhere在最低指导下进行简单到中等复杂度RPA项目的知识、技术和心态。 RPA是一项令人兴奋的新技术,被视为使用新的先进技…...
rust字面量
字面量就是值。值最终必须编码成二进制存储在某块内存上。 变量与字面量的关系就像杯子和水的关系。 字面量是有类型的。字面量类型有:布尔、数字、文本、字节 一、布尔 类型是bool true false 二、数字 通过后缀表示类型 通过前缀表示进制 通过 “_” 来分割数…...
Unix Network Programming Episode 79
‘gai_strerror’ Function The nonzero error return values from getaddrinfo have the names and meanings shown in Figure 11.7. The function gai_strerror takes one of these values as an argument and returns a pointer to the corresponding error string. #incl…...
Cesium展示——wkt 数据绘制
文章目录 需求分析1. 第一步,数据类型转换2. 第二步,数据渲染需求 WKT 是什么:WKT 简介 在这里,我选择将 Cesium 中将wkt数据转化为geoJSON格式后渲染至地球上 分析 1. 第一步,数据类型转换 npm install terraformer-wkt-parser --savelet wkts =...
打造完美家庭空间,让生活更加舒适
在现代繁忙的都市生活中,家是人们温暖而舒适的避风港。而如何打造一个恰到好处的家庭空间,成为了许多人心中的追求。今天,就让我们来探索一些空间布局方案,为您的家庭营造一个完美融合功能与美感的舒适空间。 🏠&…...
解决loadDep:omelette: sill install loadAllDepsIntoIdealTree
报错信息如下: 解决方案: 1、设置为淘宝的镜像源 npm config set registry https://registry.npm.taobao.org 2、 命令检验是否成功 npm config get registry 3、继续运行npm install即可 npm install 运行效果:...
【深蓝学院】手写VIO第2章--IMU传感器--作业
这次作业坑很多,作业说明的不清楚,摸索了很长时间才将此次作业完成,在这里进行记录。 1. T1 1.1 题干 1.2 解答 1.2.1 法1,ros related方法 不知道为什么我的launch不了,在imu_utils目录下面建立build后࿰…...
Android多线程学习:线程
一、概念 进程:系统资源分配的基本单位,进程之间相互独立,不能直接访问其他进程的地址空间。 线程:CPU调度的基本单位,线程之间共享所在进程的资源,包括共享内存,公有数据,全局变量…...
canvas 入门
canvas 入门 canvas是干什么的?canvas 绘制直线canvas画虚线canvas 绘制三角形canvas 绘制正方形canvas 绘制圆形、圆弧与椭圆canvas绘制文本canvas绘制图片 canvas是干什么的? <canvas> 是HTML5中的标签,它是一个容器,可以…...
建议收藏!混迹职场多年总结出的8大技巧!
1. 不要吃“哑巴”亏:不管在什么企业,一定要“会说话”,敢于表达自己,但是又兼顾身边人的感受,考虑好自己的言行将会带来的后果。良好的沟通技巧对于在职场中建立良好的人际关系和解决问题至关重要。学会倾听、表达和理…...
OpenCV4(C++)—— 视频和摄像头的加载、显示与保存
文章目录 一、加载与显示二、保存 一、加载与显示 视频或摄像头的加载是使用 cv::VideoCapture 类。(这个类和 ifstream 类比较相似,视频或摄像头的加载和文本文件操作是大致相同。主要步骤:(1)加载(打开&a…...
excel功能区(ribbonx)编程笔记6-box的使用
box元素用来在组里指定的控件周围放置一个可视的框,其主要目的是将控件作为一个单元组合在一起。 通常情况下,分配到组中的每个控件都被放置在先前的控件下面直到该列被填满,然后下一个控件被放置在其右侧列的顶行。然而,通过在框里面组合命令,可以将几个控件视作一个整体…...
oralce配置访问白名单的方法
目录 配置sqlnet.ora文件 重新加载使配置生效 注意事项 Oracle数据库安全性提升:IP白名单的配置方法 随着互联网的发展,数据库安全问题也越来越严重。Oracle是目前使用较为广泛的一款数据库管理系统,而IP白名单作为提升数据库安全性的有效…...
ToBeWritten之让响应团队参与并做好沟通
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…...
ffmpeg ts 关于av_seek_frame
1 ffmpeg命令行 一般对视频文件的裁剪 我们通过一行 ffmpeg命令行即可实现,比如 ffmpeg -ss 0.5 - t 3 - i a.mp4 vcodec copy b.mp4 其中 -ss 放置较前 开启精准seek定位 对于mp4而言 seek将从moov中相关索引表查找 0.5s时刻附近最近的关键帧 (此描述…...
【C++】set map 的底层封装
在了解底层封装之前除了对set和map的使用情况要有一定了解,还需要先学习一下二叉搜索树,AVL树,红黑树这些数据结构。 【C】二叉搜索树 【C】AVL树 & 红黑树 RBTree.h enum Colour {RED,BLACK };template<class T> class RBTreeNo…...
JavaWeb整体介绍
JavaWeb整体介绍 什么是Java Web Web:全球广域网,也称为万维网(www),能够通过浏览器访问的网站JavaWeb:是使用Java技术解决相关web互联网领域的技术栈(就是用java开发网站) 网页&a…...
一些常见分布-正态分布、对数正态分布、伽马分布、卡方分布、t分布、F分布等
目录 正态分布 对数正态分布 伽马分布 伽马函数 贝塔函数 伽马分布 卡方分布 F分布 t分布 附录 参考文献 本文主要介绍一些常见的分布,包括正态分布、对数正态分布、伽马分布、卡方分布、F分布、t分布。给出了分布的定义,推导了概率密度函数&…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
Pandas 可视化集成:数据科学家的高效绘图指南
为什么选择 Pandas 进行数据可视化? 在数据科学和分析领域,可视化是理解数据、发现模式和传达见解的关键步骤。Python 生态系统提供了多种可视化工具,如 Matplotlib、Seaborn、Plotly 等,但 Pandas 内置的可视化功能因其与数据结…...
智能体革命:企业如何构建自主决策的AI代理?
OpenAI智能代理构建实用指南详解 随着大型语言模型(LLM)在推理、多模态理解和工具调用能力上的进步,智能代理(Agents)成为自动化领域的新突破。与传统软件仅帮助用户自动化流程不同,智能代理能够自主执行工…...
项目研究:使用 LangGraph 构建智能客服代理
概述 本教程展示了如何使用 LangGraph 构建一个智能客服代理。LangGraph 是一个强大的工具,可用于构建复杂的语言模型工作流。该代理可以自动分类用户问题、分析情绪,并根据需要生成回应或升级处理。 背景动机 在当今节奏飞快的商业环境中,…...
