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

线程安全问题的原因及解决方案

                要想知道线程安全问题的原因及解决方案,首先得知道什么是线程安全,想给出一个线程安全的确切定义是复杂的,但我们可以这样认为:如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该的结果,则说这个程序是线程安全的。例如:使用两个线程分别对同一个变量进行修改,得出的结果与使用一个线程对这个变量进行修改的结果不同,这样的问题就可以说是该程序不是线程安全的。知道了什么是线程安全后,这样才好分析线程安全问题的原因及解决方案。

        原因1)多个线程之间的调度顺序是随机的,操作系统使用抢占式策略来执行线程(根本原因),并且该原因无法改变,当前主流的操作系统都是如此:例如当两个线程分别对同时一个变量count++,则会使每次得到的结果不同,因为CPU的调度是抢占式的,且count++实际上有着三步操作,这就将导致得到的结果不同。因为count++的三步操作为:

1. 从内存把数据读到 CPU
2. 进行数据更新
3. 把数据写回到 CPU
因此当多个线程进行count++时,就会导致如线程1刚进行完操作1后,线程2抢占了CPU,使得线程1没有及时将数据更新并将数据写回到CPU上,所以线程2读的数据与线程1读的数据相同,因此它们将数据更新后并写回到CPU也是相同,因此相当于count只进行了一次count++,
它们之中的顺序是任意的,因此得到的结果也是不确定的,但一定小于原本要得到的值(count++分别在多个线程中进行了多次)。
原因2)多个线程同时修改同一个变量,容易产生线程安全问题。可以通过调整代码结构进行避免。
原因3)修改操作不是原子的:原子性则是不可再分,如count++,可以分为三步操作。也可通过代码来进行封装成原子的来解决,也就是通过锁来进行互斥,使得有个线程操作时,别的线程不能进行操作。解决方法通常是加锁。
原因4)内存可见性引起的线程安全问题。当判断条件一个线程里面没有改变的话,那么编译器就会进行优化,令其只进行一次判断,后续就不再判断,倘若在另一个线程将其条件改变的话,但再这个线程里不会感觉的到,因此会继续按照之前的判断来进行。解决方法通常是对其条件进行volatile来进行修饰。
public static volatile int count = 0;//倘若没有volatile,则该代码会一直进行下去
public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {while(count == 0){;}});Thread t2 = new Thread(() -> {try {Thread.currentThread().sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}count = 1;});t1.start();t2.start();t1.join();
}
原因5)指令重排序引起的线程安全问题。
上述的例子的线程安全问题主要有原因1,2,3组成,因此,若想解决,我们只需给count++进行加锁就行。这样就使的count++操作变成原子的,当count++时,倘若又有一个线程要进行count++,就会产生阻塞,知道先进行count++的线程结束,另一个线程才能进行count++操作。
通常来说,大部分解决线程安全问题,只需要进行加锁就行。

相关文章:

线程安全问题的原因及解决方案

要想知道线程安全问题的原因及解决方案,首先得知道什么是线程安全,想给出一个线程安全的确切定义是复杂的,但我们可以这样认为:如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该的结果,…...

基于matlab中点放炮各类地震波时距曲线程序

完整程序&#xff1a; clear all dx50;x-500:dx:500;%炮检距 h100;V11500; theta25*pi/180; V2V1/sin(theta); t1sqrt(x.*x4*h*h)/V1;%反射波时距曲线 t2abs(x)./V1;%直达波时距曲线 %折射波时距曲线 xm2*h*tan(theta);%求盲区 k1; for i1:length(x) if x(i)<-xm …...

vue中el-dialog 中的内容没有预先加载,因此无法获得内部元素的ref 的解决方案 使用强制提前加载dialog方法

问题描述 在没有进行任何操作的时候&#xff0c;使用 this.$refs.xxxx 无法获取el-dialog中的内部元素&#xff0c;这个问题会导致很多bug&#xff0c;其中目前网络上也有许多关于这个问题的解决方案&#xff0c;但是大多数是使用el-dialog中的open在dialog打开的时候使用thi…...

vue-h5移动Web的rem配置

H5移动的适配方案 rem rem适配方案是兼容性比较好的移动端适配方案&#xff0c;rem支持大部分的移动端系统和机型。 rem是相对于根元素的字体大小的单位。本质上就是一个相对单位&#xff0c;和em的区别是&#xff1a;em是依赖父元素的字体来计算&#xff0c;rem是依赖根元素…...

企业级数据仓库-数仓实战

数仓实战 安装包大小 安装清单 环境搭建 一、环境搭建01&#xff08;机器准备&#xff09; 准备好三台虚拟机&#xff0c;并进行修改hostname、在hosts文件增加ip地址和主机名映射 。 1、设置每个虚拟机的hostname vi /etc/sysconfig/network 修改HOSTNAMEnode02修改hostna…...

Spring Boot 下载文件(word/excel等)文件名中文乱码问题|构建打包不存在模版文件(templates等)

Spring Boot 下载文件(word/excel等)文件名中文乱码问题&#xff5c;构建打包不存在模版文件(templates等) 准备文件&#xff0c;这里我放在resource下的templates路径 在pom中配置构建打包的资源&#xff0c;更新maven 如果使用了assembly打包插件这样配置可能仍不生效&#…...

Ansible数组同步至Shell脚本数组中

1、ansible中定义数组&#xff0c;我以 ccaPojectList 数组为例子,如下图数组内容 2、需要写一个j2模板的Shell脚本&#xff0c;在j2模板的Shell脚本中引用ansible的 ccaPojectList 数组&#xff0c;大致如下图&#xff1a; {% for item in ccaPojectList %} "{{ item }…...

私域流量的优势

私域流量是指由自身品牌或个人拥有并具备完全掌控权的流量资源。它相比于传统的广告推广&#xff0c;拥有独特的优势。 首先&#xff0c;私域流量能够更加精准地定位目标用户&#xff0c;实现精准传播。不再盲目投放广告&#xff0c;而是通过建立自身社群、粉丝群&#xff0c;获…...

Java 中“1000==1000”为false,而”100==100“为true?

如果你运行下面的代码: Integer a 1000, b 1000; System.out.println(a b);//1Integer c 100, d 100; System.out.println(c d);//2你会得到: false true基本知识&#xff1a;我们知道&#xff0c;如果两个引用指向同一个对象&#xff0c;用表示它们是相等的。如果两…...

片上网络(1)概述

前言 NoC&#xff1a;On-Chip Networks&#xff0c;片上网络。 由于多核乃至众核时代的到来&#xff0c;用于连接它们的可扩展、低延迟、大带宽的通信结构变得至关重要。 在核心较少时&#xff0c;总线Bus和矩阵/交叉开关Crossbar是主要的互联结构。总线可以提供较低的传输延迟…...

使用 React Native 针对 Android 进行开发

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 概述 通过安装所需工具开始使用 React Native 创建新的 React Native 项目 本指南将有助于开始使用 Windows 上的…...

LeetCode 每日一题 2023/9/11-2023/9/17

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录 9/11 630. 课程表 III9/12 1462. 课程表 IV9/13 2596. 检查骑士巡视方案9/14 1222. 可以攻击国王的皇后9/15 LCP 50. 宝石补给9/16 198. 打家劫舍9/17 9/11 630. 课程表 II…...

Linux系统调试篇——GDBSERVER远程调试

文章目录 安装 GDBSERVERgdbserver 用法具体步骤 本篇讲解如何使用gdbserver对目标开发板上的程序进行远程调试。 安装 GDBSERVER 首先在开发板上安装 gdbserver&#xff1a; apt install gdbservergdbserver 用法 gdbserver用法描述&#xff1a; Usage: gdbserver [OPTION…...

前端实现打字效果

前端实现打字效果 不带光标 只一次播放 HTML <!-- 需要在初始化的时候不显示文字 --> <div id"typing"></div>CSS #typing {position: relative;font-size: 24px;font-family: Arial, sans-serif;padding: 10px; }JS const text "要显…...

Unix和Linux、GNU和GPL、RHEL和Centos、Debian和Ubuntu

文章目录 Unix和LinuxGNU和GPLGNU/Linux名称的来源RHEL和CentosDebian和Ubuntu 以上都是操作系统&#xff0c;服务器操作系统、桌面操作系统。 对于刚刚接触Linux系统或者从事运维相关工作的人来说&#xff0c;肯定会听过很多名词&#xff0c;但是不知道他们的区别和联系&#…...

InfiniBand vs 光纤通道,存储协议的选择

数字时代&#xff0c;数据量爆发增长&#xff0c;企业越来越迫切地追求高吞吐量、低延迟和更高性能的网络基础设施&#xff0c;存储协议的选择变得愈发至关重要。在众多存储协议中&#xff0c;InfiniBand和光纤通道备受关注。本文旨在深入探讨InfiniBand和光纤通道作为存储协议…...

第2章_freeRTOS入门与工程实践之单片机程序设计模式

本教程基于韦东山百问网出的 DShanMCU-F103开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id724601559592 配套资料获取&#xff1a;https://rtos.100ask.net/zh/freeRTOS/DShanMCU-F103 freeRTOS系列教程之freeRTOS入…...

python LeetCode 刷题记录 58

题目 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 示例 输入&#xff1a;s "Hello World" 输出&#xff1a;5 解释&am…...

HarmonyOS开发:那些开发中常见的问题汇总(一)

前言 本来这篇文章需要讲述静态共享包如何实现远程依赖和上传以及关于静态共享包私服的搭建&#xff0c;非常遗憾的告诉大家&#xff0c;由于组织管理申请迟迟未通过&#xff0c;和部分文档官方权限暂未开放&#xff0c;关于这方面的讲解需要延后了&#xff0c;大概需要等到202…...

新能源汽车驱动电机的基本知识

学习目标:了解电机的基本知识。能力目标:培养学生搜集和整理相关资料的能力。素质目标:培养学生良好的职业素养。额定电店.在夫见定条件下电池工作的*于佳 电压知识准备术语和定义。 (1)驱动电机系统 通过有效的控制策略将动力蓄电池提供的直流电转化为交流实现电机的正转以及反…...

流媒体协议——RTSP

RTSP RTSP(Real Time Streaming Protocol):实时流媒体协议&#xff0c;是基于文本的协议&#xff0c;采用ISO10646字符集&#xff0c;使用UTF-8编码 RTSP-over-TCP&#xff0c;默认端口554 RTSP-over-HTTP&#xff0c;默认端口为8080 RTSP OVER WebSocket 默认端口为 80&am…...

Arcgis提取点数据经纬度

Arcgis提取点数据经纬度 现已打开tiff影像和采样点的shape文件。目标是提取采样点的经纬度信息然后导出。 打开数据管理工具-要素-添加XY坐标 在点的图层上右击打开属性表时&#xff0c;经纬度信息已经添加到属性表中。 在属性表的左上角中点击导出&#xff0c;导出为文本文…...

【小记录】jupyter notebook新版本

手欠升级 &#x1f605;今天手贱&#xff0c;在anaconda navigator里面更新了最新版本的spyder&#xff0c;然后莫名奇妙地jupyter notebook就打不开了&#x1f605;&#xff0c;报错说缺少模块”ModuleNotFoundError: No module named jupyter_server.contents“&#xff0c;…...

Ubuntu安装深度学习环境相关(yolov8-python部署)

Ubuntu安装深度学习环境相关(yolov8-python部署) 本文将从如下几个方面总结相关的工作过程&#xff1a; Ubuntu系统安装(联想小新pro16) 2.显卡驱动安装3.测试深度学习模型 1. Ubunut 系统安装 之前在台式机上安装过Ubuntu&#xff0c;以为再在笔记本上安装会是小菜一碟&…...

jmeter采集ELK平台海量业务日志( 采用Scroll)

由于性能测试需要&#xff0c;需采集某业务系统海量日志&#xff08;百万以上&#xff09;来使用。但Elasticsearch的结果分页size单次最大为10000&#xff08;运维同事为保证ES安全&#xff09;。为了能够快速采集ELK平台业务日志&#xff0c;可以使用以下2种方式采集&#xf…...

React 全栈体系(五)

第三章&#xff1a;React 应用(基于 React 脚手架) 一、使用 create-react-app 创建 react 应用 1. react 脚手架 xxx 脚手架: 用来帮助程序员快速创建一个基于 xxx 库的模板项目 包含了所有需要的配置&#xff08;语法检查、jsx 编译、devServer…&#xff09;下载好了所有…...

动态规划——状态机模型

什么是状态机模型&#xff1f;其实大部分dp问题都可以算是状态机&#xff0c;因为对于一个物品&#xff0c;例如01背包&#xff0c;无非是选与不选两种状态&#xff0c;这两种状态就构成了一个状态机。状态机就是一种用来描述对象或者系统在不同状态之间迁移的模型。 那么状态机…...

合宙Air724UG LuatOS-Air LVGL API控件-图片(Gif)

图片&#xff08;Gif&#xff09; GIF图片显示&#xff0c;core版本号要>3211 示例代码 方法一 -- 创建GIF图片控件 glvgl.gif_create(lvgl.scr_act()) -- 设置显示的GIF图像 lvgl.gif_set_src(g,"/lua/test.gif") -- gif图片居中 lvgl.obj_align(g, nil, lvgl…...

【C语言】指针和数组笔试题解析(2)

【C语言】指针和数组笔试题解析&#xff08;1&#xff09;&#xff0c; 这是第一篇关于sizeof与strlen在指针中的应用&#xff0c;而这一篇主要讲解在各种情形下的灵活运用&#xff0c;也是大厂中经典的面试题 第一题&#xff1a; int main() {int a[5] { 1, 2, 3, 4, 5 };in…...

3.3 DLL注入:突破会话0强力注入

Session是Windows系统的一个安全特性&#xff0c;该特性引入了针对用户体验提高的安全机制&#xff0c;即拆分Session 0和用户会话&#xff0c;这种拆分Session 0和Session 1的机制对于提高安全性非常有用&#xff0c;这是因为将桌面服务进程&#xff0c;驱动程序以及其他系统级…...

可以做盗版漫画网站吗/网站制作建设

使用 ThreadPoolExecutor表示一个线程池。Executors类则扮演着线程池工厂的角色&#xff0c;通过Executors可以获取特定功能的线程池Executors工厂创建线程池普通线程池public static ExecutorService newFixedThreadPool(int nThreads)public static ExecutorService newFixe…...

石家庄网站建设吧/凡科建站客服电话

Math EXP10 格式&#xff1a;number : EXP10(x)说明&#xff1a;将x的以10为底的指数值赋给number http://www.yfdmt.com/multimedia/authorware/yufeng/function1.htm isnan isinf 在linux下有两个函数 isnan(x)isinf(x) 对应在windows下的函数&#xff1a; _isnan(x)!_finit…...

游戏运营备案官方网站/云盘搜

赋值语句的是内存地址引用&#xff0c;不是拷贝拷贝是导入copy包&#xff0c;分copy和deepcopy两种&#xff0c;即浅拷贝和深拷贝对于非嵌套数据 copy.copy 和 copy.deepcopy 没有区别 都会开辟新空间 存储数据有嵌套的数据 copy.copy没有办法保证数据的独立性,拷贝第一层的数据…...

服装效果图网站/北京网站制作公司

http://www.gettyicons.com/free-icon/107/basic-icon-set/free-up-icon-png/ 转载于:https://www.cnblogs.com/keepsilence/archive/2012/06/07/2540312.html...

asp网站制作实例教程/如何做品牌宣传与推广

数据库之存储过程和存储函数(六) 什么是存储过程 ​ 存储过程是一组为了完成某项特定功能的SQL语句集&#xff0c;其实质就是一段存储在数据库中的代码。它可以由声明式的sql语句和过程式sql语句组成。 优点 1. 可以增强sql语言的功能和灵活性 2. 良好的封装性3. 高性能4. 减少…...

杀手杰夫链接网站代码/公众号推广引流

众包&#xff08;Crowdsourcing&#xff09;是这样一个过程&#xff1a;征求大批社区中的群众去完成一个任务&#xff0c;传统上这种任务由组织从内部选择一拨人来完成&#xff0c;多数是雇员或合同工。众包测试&#xff08;Crowdsourced testing&#xff09;利用众包的有效性和…...