【线程安全问题的原因和方法】【java形式】【图片详解】
在本章节中采用实例+图片的方式,以一个学习者的姿态进行描述问题+解决问题,更加清晰明了,以及过程中会发问的问题都会一一进行呈现
目录
- 线程安全
- 演示线程不安全情况
- 图片解释:
- 将上述代码进行修改【从并行转化成穿行的方式】
- 不会出现问题的可能
- 埋坑问题
- 总结(线程安全问题产生原因)
- 如何解决线程安全问题
- 1.根本原因:
- 2.多线程同时修改一个变量
- 3.修改操作,不是原子的
- 注意:
线程安全
概念:一段代码在多线程并发执行的情况下,出现bug的情况(实际结果与预期结果不符合),预期结果:一般是由别人来预期,此时这种情况是“线程不安全”
演示线程不安全情况
eg:(如果我们需要计算一个20000;两个线程每个线程执行10000次看其的一个情况)
public class Test {public static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{for (int i = 0; i < 10000; i++) {count++;}});Thread t2 = new Thread(()->{for (int i = 0; i < 10000; i++) {count++;}});t1.start();t2.start();Thread.sleep(1000);System.out.println(count);}
}
最终运行的结果为:
对代码进行解释:
其中
Thread t1 = new Thread(()->{
for (int i = 0; i < 10000; i++) {
count++;
}
});
对应的是3个cpu的操作:
- load:将内存中的count加载到寄存器上
- add:把寄存器中的内容进行+1;
- save:把寄存器当中的内容保留在内存上
所以最终会出现这样的情况
图片解释:
将上述代码进行修改【从并行转化成穿行的方式】
//只需要使用join方法就可以将并行执行的方式改为串行的方式
public class Test {public static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{for (int i = 0; i < 10000; i++) {count++;}});Thread t2 = new Thread(()->{for (int i = 0; i < 10000; i++) {count++;}});t1.start();t1.join();t2.start();t2.join();Thread.sleep(1000);System.out.println(count);}
}
最终的结果为:20000
此时上述的反应就被称为——“线程不安全”
不会出现问题的可能
- 如果线程重复的次数少:其运行的速度非常快,会出现一个线程执行完了,另一个线程还没有开始执行——结果就是正确的
eg:
public class Test {public static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{for (int i = 0; i < 10; i++) {count++;}});Thread t2 = new Thread(()->{for (int i = 0; i < 10; i++) {count++;}});t1.start();//t1.join();t2.start();//t2.join();Thread.sleep(1000);System.out.println(count);}
}
此时的结果就是正确的;
由于他的速度非常快,在状态转化的过程当中前一个线程就已经完成了操作
埋坑问题
- 在上述的代码当中是否可能出现最终打印的结果<5000
答:可能会出现
解释图片:
在上面的情况中会出现最终打印的1 - 那由上面问题 ,是否最终在我们之前写的代码中出现打印1的情况
答:这个是不太可能的
因为执行的次序是抢占资源的方式,在这个过程中,很少可能会出现4999都只由一个线程执行,然后由两一个线程进行收尾
总结(线程安全问题产生原因)
- 根本原因:操作系统对线程的调度是随机的,抢占式执行的方式
- 多个线程同时修改同一个变量
以下是不会出现问题的情况:
一个线程修改一个变量
多个线程不同时修改同一个变量
多个线程修改不同变量
多个线程读取同一变量 - 修改操作不是原子的
进行解释:如果修改操作只对应一个cpu质量——此时原子的(例如没有多线程的时候,java当中的main线程就不会发生任何的问题)
如何解决线程安全问题
将他产生的原因尽行打破
1.根本原因:
这个是操作系统底层的设定,不能进行改变
或者自己写一个操作系统:两大难点1》技术上会非常难2》推广上会更加难
2.多线程同时修改一个变量
解决方法:调整代码结构【但是这种方法并不是通用的】
3.修改操作,不是原子的
这个是java当中解决线程安全问题,最主要的解决方案
加锁
关键字:synchronized
synchronized(加锁对象){——加锁操作
执行相关代码
}——解锁操作
加锁操作,不是将整个线程锁死在cpu上,禁止这个线程被其他的调度走,但是禁止其他线程重新加这个锁,避免其线程成的操作
java当中可以使用这个关键字修饰任何对象
只有两个线程针对同一个对象加锁操作,才会产生互斥效果
锁对象并不会影响这个对象其他方面的使用
结果展示:
public class Test2 {public static int count = 0;public static void main(String[] args) throws InterruptedException {Object o = new Object();Thread t1 = new Thread(()->{synchronized (o) {for (int i = 0; i < 10; i++) {count++;}}});Thread t2 = new Thread(()->{synchronized (o) {for (int i = 0; i < 10; i++) {count++;}}});t1.start();//t1.join();t2.start();//t2.join();Thread.sleep(1000);System.out.println(count);}
}
上述代码的最终的结果就可以被正确打印
对代码进行的解释:
注意:
在此过程中,只有针对同一个对象加锁才会有效果
在一般情况下:synchronized是对this进行加锁
当synchronized修饰static修饰的变量时,相当于针对类对象尽心的加锁操作
下一张会讲到死锁的问题,不要走开哦!!!!
相关文章:
【线程安全问题的原因和方法】【java形式】【图片详解】
在本章节中采用实例图片的方式,以一个学习者的姿态进行描述问题解决问题,更加清晰明了,以及过程中会发问的问题都会一一进行呈现 目录 线程安全演示线程不安全情况图片解释: 将上述代码进行修改【从并行转化成穿行的方式】不会出…...
Cocos Creator Shader入门实战(六):使用setProperty动态设置材质属性,以及材质常用接口
引擎:3.8.5 您好,我是鹤九日! 回顾 上篇文章,我们主要讲解了关于材质的使用,主要有这么几点: 一、没有Effect资源,材质无从说起。 二、材质的构建,支持编译器和代码的动态构建 三…...
编程题记录3
九宫幻方 题目链接:https://www.lanqiao.cn/problems/100/learning/?page1&first_category_id1&second_category_id3&tags%E7%9C%81%E8%B5%9B&tag_relationintersection 先旋转、镜像得到所有的情况,可以发现情况是可以暴力得出的。…...
Geotools自动识别SLD并生成图例图片实战-以Polygon数据为例
目录 前言 一、Geotools与SLD制图基础 1、SLD是什么 2、SLD有什么用 二、SLD文件的解析与读取 1、SLD结构介绍 2、SLD实例展示 3、SLD读取方法 三、图例生成与展示 1、图例生成流程 2、图例生成实战 3、图例生成展示 四、结论 前言 在地理信息系统(GIS&…...
windows docker如何修改 默认的Container memory usage
参考:https://forums.docker.com/t/docker-on-windows-11-with-wsl2-does-not-use-the-memory-i-set-in-wslconfig/144404/3 参考:https://learn.microsoft.com/en-us/windows/wsl/wsl-config...
LabVIEW液压传动系统教学仿真平台
本文介绍了一种基于LabVIEW的液压传动系统教学仿真平台,该平台采用“老师讲解、线上仿真、线下操作”的复合实验模式,旨在提高实验教学的效率与安全性。通过实例验证,展示了该平台在教学和实际操作中的应用效果,同时也为液压传动系…...
Java实习生面试题(2025.3.23 be)
一、v-if与v-show的区别 v-show 和 v-if 都是 Vue 中的条件渲染指令,它们的主要区别在于渲染策略:v-if 会根据条件决定是否编译元素,而 v-show 则始终编译元素,只是通过改变 CSS 的 display 属性来控制显示与隐藏。 二、mybatis-…...
OpenCV第2课 OpenCV的组成结构与图片/视频的加载及展示
1.OpenCV 的组成结构 2.OpenCV 的具体模块 3. 图像的读取 4. 视频的读取 1.OpenCV 的组成结构 OpenCV 是由很多模块组成的,这些模块可以分成很多层: 最底层是基于硬件加速层(HAL)的各种硬件优化。再上一层是opencv_contrib 模块所包含的OpenCV 由其他开发人员所贡献的代…...
Blender导出fbx到Unity找不到贴图的问题
fbx导入Unity材质能不能找到贴图是一件玄学的事情。常见的情况是有些材质能找到,有些找不到: 可能有用的方法 解决方法1:把贴图文件复制过去,模型reimport; 解决方法2:导出时路径模式选复制,内…...
kafka的文章
1.面试的问题 要点 至多一次、恰好一次数据一致性超时重试、幂等消息顺序消息挤压延时消息 1.1 kafaka 生产消息的过程。 在消息发送的过程中,涉及到了两个线程,一个是main 线程,一个是sender 线程。在main 线程中创建了一个双端队列 Reco…...
Go常见问题与回答(下)
文章目录 1、通过指针变量 p 访问其成员变量 name,有哪几种方式?2、代码,说出结果3、扩容提,代码,说出结果4、指出下面这段代码的错误之处5、是否通过编译6、关于字符串连接,下面语法正确的是7、关于iota&a…...
vue3中如何缓存路由组件
在 Vue3 中缓存路由组件,主要借助<keep-alive>组件来实现,具体方法如下: 1. 全局缓存路由组件 在 App.vue 等根组件中,直接将<router-view>包裹在<keep-alive>标签内,这样所有的路由组件都会被缓存…...
云服务器怎么防御ddos攻击呢?
防御DDoS攻击是保障云服务器稳定运行的关键措施,以下是综合多种防护策略的详细方案: 1. 启用云服务商提供的DDoS防护服务 高防IP/流量清洗: 将业务流量接入云服务商的高防IP,由专业清洗中心过滤恶意流量,仅放行正常请求…...
Log4j2 的核心实现和源码分析
Log4j2 的核心实现和源码分析 1. 核心组件 1.1 Logger 功能:负责记录日志信息。实现:org.apache.logging.log4j.Logger 接口,org.apache.logging.log4j.core.Logger 类。1.2 Appender 功能:负责将日志信息输出到不同的目的地,如文件、控制台等。实现:org.apache.loggin…...
【深度学习】【目标检测】【OnnxRuntime】【C++】YOLOV3模型部署
【深度学习】【目标检测】【OnnxRuntime】【C】YOLOV3模型部署 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】【目标检测】【OnnxRuntime】【C】YOLOV3模型部署前言Windows平台搭建依赖环境模型转换--pytorch转onnxONNXRuntime推…...
四种跨模态行人重识别可视化方法
1.Gradcam 2.检索可视化 3.tsne图 4.距离分布 需要的私聊,代码需要付费...
8个DeepSeek文章润色指令
今天道叔给各位文字工作者安利DeepSeek的8个神仙级润色指令(附真实案例拆解),建议搭配冰美式食用更佳↓↓↓ 一、【学术黑话翻译器】 适用场景:给投资人看的BP/行业白皮书/专家访谈实录 指令公式:"将以下内容转化为通俗易懂的行业洞察…...
解决PowerShell下Git中文乱码问题
解决PowerShell下Git中文乱码问题 在使用Git进行版本控制时,许多开发者可能会遇到中文乱码的问题,尤其是在Windows环境下使用PowerShell时。这不仅影响代码的阅读和提交,还可能导致一些不可预见的错误。本文将详细探讨如何在PowerShell下解决…...
oracle数据库(数据库启动关闭/sqlplus登录及基本操作/设置字符集/distinct去重)
目录 1. Oracle数据库启动 2. Oracle数据库关闭 3. sqlplus登录Oracle数据库 3.1 使用sqlplus登录Oracle数据库 3.2 使用sqlplus登录Oracle数据库 3.3 远程登录 3.4 解锁用户 3.5 修改用户密码 3.6 查看当前语言环境 4. sqlplus基本操作 4.1 显示当前用户 4.2 查看当前用户…...
mapreduce时,客户端做哪些事
在MapReduce过程中,客户端(Client)是用户提交作业的入口,负责作业的初始化、配置、资源提交和作业监控。以下是客户端在整个流程中的具体职责和操作步骤: 1. 作业配置与参数解析 设置作业属性: 定义MapRed…...
DeepBI:重构流量逻辑,助力亚马逊广告实现高效流量增长
在日益激烈的跨境电商竞争环境中,广告投放早已从“粗放撒网”走向“精细化运营”。尤其是在亚马逊这样一个成熟且竞争白热化的平台,如何在广告预算有限的前提下实现高效曝光、精准触达、稳定转化,成为众多卖家和运营团队面临的核心挑战。 De…...
Linux内核的页面错误:原因与解决方案
当程序访问虚拟内存中的一个页面时,如果该页面当前不在物理内存中,就会触发一个称为"page fault"(页异常)的异常。操作系统需要处理这个异常,并将所需页面从磁盘加载到内存中。实现虚存管理的一个关键是page…...
LORA 中的 梯度外积是什么意思; 方差和协方差的实际含义:衡量变量的离散程度和变量间的线性相关性
LORA 中的 梯度外积是什么意思 目录 LORA 中的 梯度外积是什么意思**一、梯度外积的定义****二、示例说明****步骤1:计算单样本梯度****步骤2:计算梯度外积****三、梯度外积的作用****四、总结**方差和协方差的实际含义:衡量变量的离散程度和变量间的线性相关性**一、方差(…...
XSS复现漏洞简单前八关靶场
靶场不需要安装任意环境 链接如下:XSS Game - Learning XSS Made Simple! | Created by PwnFunction 目录 XSS Game 第一关:Ma Spaghet! 第二关:Jefff 第三关:Ugandan Knuckles 第四关:Ricardo Milos 第五关&am…...
3.24-3 接口测试断言
一.postman 断言 1.断言再test中 #状态码是否等于200 tests["Status code is 200"] responseCode.code 200; #断言响应时间小于200ms tests["Response time is less than 200ms"] responseTime < 200; #断言响应体包含内容 tests["Body…...
《鸿蒙携手AI:解锁智慧出行底层逻辑》
在科技飞速发展的当下,智慧出行成为人们对未来交通的美好期许,而鸿蒙系统与人工智能的深度融合,正为这一愿景的实现提供强大助力。从技术原理角度深入剖析,鸿蒙系统究竟如何支撑人工智能在智慧出行场景中的应用呢?这背…...
【AVRCP】探寻AVRCP控制互操作性:连接、命令与设备交互
目录 一、AVCTP连接管理 1.1 AVCTP连接建立 1.2 AVCTP连接释放 二、AV/C命令的操作流程 2.1 AV/C命令交换流程 2.2 AV/C命令类型 三、AVRCP特定命令 四、AVRCP浏览命令 五、OBEX连接管理 5.1 OBEX连接建立 5.2 OBEX连接释放 六、总结 七、参考资料 AVRCP对于实现设…...
Mybatis-Plus知识点详解
Mybatis-plus(简称MP),基于Mybatis的增强工具,保留了Mybatis的所有功能,同时增加了通用的CRUD,条件构造器,分页插件等等实用工具 特性 即拿即用:通过通用Mapper和Service,无需编写XML既可以完成单表CURE操作 Lambda支持:使用Lambda表达式构建查询条件,避免硬编码字段名,提升代…...
紧凑交叉引用表
嗯,用户问的是“compact xref table”,也就是紧凑型交叉引用表。我之前在回答中提到过交叉引用流(XRef Stream),但可能需要更详细地解释两者的区别和联系。根据搜索结果中的网页1,传统的Xref表以文本形式存…...
CMake 详解:跨平台构建系统的入门与进阶
目录 一、相关知识点 1. 什么是cmake,为什么使用? 2. 构建过程 二、CMake使用流程 1. 创建 CMakeLists.txt 文件 2. 配置构建目录 3. 运行cmake 4. 运行make编译 一、相关知识点 1. 什么是cmake,为什么使用? CMake 是一个开…...
【架构设计】学习路径
掌握前置知识后,学习架构设计需要从理论认知到实践落地逐步推进。以下是系统化的学习路径,结合具体案例与实操建议,帮助你快速进阶: 一、构建架构思维基础 1. 理解架构设计的核心目标 关键问题驱动设计: 每个架构决策…...
14、Python 枚举与类型注解进阶
Python 枚举与类型注解进阶 文章概述 本文深入探讨Python中枚举(Enum)与类型注解的高级应用场景。通过剖析Enum类的核心特性、dataclass装饰器的工程实践、静态类型检查工具mypy的集成使用,结合状态机等实际案例,系统性地提升代…...
C语言 【实现电脑关机小游戏】非常好玩
引言 在时间限制内做出正确的回答,时间一到,电脑自动关机,听起来是不是很有意思,下面来看看怎么实现吧。 注意:该游戏只在windows系统下可以玩, 一、游戏原理: 在Windows系统下,通…...
【蓝桥杯速成】| 11.回溯 之 子集问题
题目一:子集 问题描述 78. 子集 - 力扣(LeetCode) 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例…...
统计矩的高阶推广:经验还是理论推导?
矩的发展既是经验总结的结果,也是数学理论推导的产物。研究者们在分析数据、描述物理现象的过程中,发现了低阶矩与日常物理概念(如质心、惯性)之间的紧密联系,而高阶矩的应用往往出现在更复杂的数学体系中,…...
SpringBoot2集成Elasticsearch8(使用spring-boot-starter-data-elasticsearch)
写在前面 使用spring-boot-starter-data-elasticsearch集成Elasticsearch8? What? 官方写的不支持啊?让我们来看下官方给出的版本建议。 官方地址: https://docs.spring.io/spring-data/elasticsearch/reference/elasticsearch/versions.…...
Postgresql源码(142)子查询提升pull_up_sublinks
1 案例 drop table t_fun01; create table t_fun01 (image_id numeric primary key, content_id varchar(50), file_code varchar(20)); create index idx3 on t_fun01(content_id); create index idx4 on t_fun01(file_code); insert into t_fun01 select t.i, t.i%10, t.i%1…...
sonar代码检测研究及平台搭建
为了实现提交代码自动检测代码缺陷,本文介绍了一种将jenkins与gitlab集成的自动检测机制,如需应用于生产级开发流程,可在此基础上进行功能丰富和扩展,本文仅进行了原理性搭建。 一、基础环境准备 与sonar配合使用的jenkins和gitlab基础软件…...
清华大学:DeepSeek从入门到精通系列教程1-9讲(持续更新中)|大礼包免费下载
导 读INTRODUCTION 今天分享由清华大学新闻与传播学院、人工智能学院双聘教授沈阳老师团队倾力打造的《DeepSeek从入门到精通系列教程1-9讲(持续更新中)》,包含:《DeepSeek:从入门到精通》《DeepSeek如何赋能职场应用》…...
使用Python可视化图结构:从GraphML文件生成节点关系图(lightrag 生成)
引言 在数据可视化领域,图结构(Graph)常用于展示实体间的复杂关系。例如,文学分析中的角色关系、社交网络中的用户互动等。本文将通过一个实际案例,演示如何使用 NetworkX 和 Matplotlib 从 GraphML 文件生成节点关系…...
排序复习_代码纯享
头文件 #pragma once #include<iostream> #include<vector> #include<utility> using std::vector; using std::cout; using std::cin; using std::endl; using std::swap;//插入排序 //1、直接插入排序(稳定) void InsertSort(vecto…...
Docker Hub Mirror 终极解决方案——0成本,超高速!
CNB Docker Mirror (cdm) CNB Docker Mirror 是一个基于 CNB 的 Docker 镜像加速工具,提供本地镜像加速功能。 功能特性 镜像加速:在本地启动连接到 CNB 环境的 Docker 镜像加速服务,然后通过配置 Docker 客户端实现镜像加速下载自动重连&…...
2000-2019年各省地方财政车船税数据
2000-2019年各省地方财政车船税数据 1、时间:2000-2019年 2、来源:国家统计局、统计年鉴 3、指标:行政区划代码、地区、年份、地方财政车船税 4、范围:31省 5、指标说明:车船税作为地方财政的重要组成部分&#x…...
c#处理算数溢出的情况
在C#中,算术运算的溢出处理可以通过 checked 和 unchecked 关键字控制,默认行为是 静默截断(unchecked模式),但可以通过配置或代码块显式调整。以下是详细说明: 1. 默认行为(unchecked模式&…...
Java「Deque」 方法详解:从入门到实战
Java Deque 各种方法解析:从入门到实战 在 Java 编程中,Deque(双端队列)是一个功能强大的数据结构,允许开发者从队列的两端高效地添加、删除和检查元素。作为 java.util 包中的一部分,Deque 接口继承自 Qu…...
简记_FPGA 硬件最小系统设计
一、FPGA板级设计的五要素 1.1、电源电路 核心电压:一般为固定值 IO电压:FPGA的IO分为多个bank,同一个bank的不同IO引脚电压相同,不同bank的电压可以不同 辅助电压:除了核心电压和IO电压,FPGA工作所需的…...
C++题目
1、内存管理 1.内存模型 栈:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。 堆:就是那些由new分配的内存块,其释放由程序员控制(一个new对应一个delete)…...
Vulhub-jangow-01-1.0.1通关攻略
第0步: 打开靶机,按下shift,出现下图界面 在此页面按下e键,进入如下界面, 将ro 替换为 rw signie init/bin/bash 替换完毕后,按下Ctrl键X键,进入如下页面 ip a查看网卡信息 编辑配置文件网卡信…...
入剖析 Android Compose 框架的关键帧动画(keyframes、Animatable)(二十三)
深入剖析 Android Compose 框架的关键帧动画(keyframes、Animatable) 引言 在当今的 Android 应用开发领域,用户体验已成为衡量一款应用成功与否的关键因素之一。而动画作为提升用户体验的重要手段,能够为应用增添生动性和交互性…...
java中的枚举类型和c,c++的有区别吗?c,c++的枚举,结构体,联合体,三种数据有什么区别和联系
Java 枚举类型与 C、C 枚举类型的区别 1. 类型安全 Java:Java 的枚举类型是类型安全的。枚举常量是枚举类型的实例,编译器会严格检查传递的参数是否为该枚举类型的有效常量。例如: java Apply enum Color { RED, GREEN, BLUE } // 编译器会检…...