加强企业门户网站建设/竞价排名营销
什么是线程安全问题
线程安全问题指的是在多线程编程环境中,由于多个线程共享数据或资源,并且这些线程对共享数据或资源的访问和操作没有正确地同步,导致数据的不一致、脏读、不可重复读、幻读等问题。线程安全问题的出现,通常是因为线程之间的并发执行导致了数据竞争(Race Condition)或者时序问题(Timing Issues)。以上是网上找到的回答,我认为只要是在多线程代码实现产生bug都可以称为线程安全问题.
线程安全问题举例
public class ThreadDemo {public static int count;public static void main(String[] args) throws InterruptedException {Thread t=new Thread(()->{for (int i = 0; i < 5000; i++) {count++;}});Thread t1=new Thread(()->{for (int i = 0; i < 5000; i++) {count++;}});t.start();t1.start();t.join();t1.join();System.out.println(count);}
}
这串代码预期结果是10000,但是无论执行多少次都达不到预期的效果
这里主要原因涉及到指令的执行顺序
因为很多操作在cpu上都会又细分为多个操作,例如count++分为 load,add,save,多线程不能穿插执行,必须要等第一个线程操作完数据保存到内存后,第二个再执行,不正常的执行顺序,可能会将其中一个线程操作的数据覆盖等影响,大概率结果会有错误
线程安全的五大原因
1.系统调度是随机的:
线程在系统中随机调度,是抢占式执行的,这种情况我无法修改和干预,当多个线程访问并修改同一内存位置的数据时,由于线程的随机调度,可能导致数据的不一致性
2.原子性问题:
某些操作(如自增、自减等)在单线程环境下是原子的,但在多线程环境下可能不是原子的。这些操作可能被拆分成多个步骤,(希望的是每个cpu指令都是原子的,要么不执行,执行就执行完为止)从而导致数据的不一致性,上面的代码线程不安全主要是原子性问题
3.内存可见性问题:
由于Java内存模型的原因,一个线程对共享变量的修改可能无法立即被其他线程看到。这可能导致线程读取到旧的数据值,从而引发问题
4指令重排序:编译器和处理器为了提高性能,可能会对指令进行重排序。但在多线程环境下,这种重排序可能会破坏代码的语义,导致线程安全问题。
线程安全问题的解决方法
加锁synchronized
public class ThreadDemo1 {public static int count;public static void main(String[] args) throws InterruptedException {String s="锁无所谓是什么变量";Thread t=new Thread(()->{for (int i = 0; i < 5000; i++) {synchronized (s){count++;}}});Thread t1=new Thread(()->{for (int i = 0; i < 5000; i++) {synchronized (s){count++;}}});t.start();t1.start();t.join();t1.join();System.out.println(count);}
}
这样锁就把count打包成一个操作了,是原子性,当执行count的时候就不会出现执行一半的情况
加锁后需要注意几点
1.此时count++操作是串行执行,其余操作例如for循环都是并行执行
2.如果两个线程同时尝试加锁,此时只有一个线程可以获取锁成功,而另一个线程就会阻塞 等待。阻塞到另一个线程释放锁之后,当前线程才能获取锁成功。
3.当t1释放锁之后,t1线程还是会同时争夺这把锁
可重入锁
可重入锁指的是,本身加锁的线程能够加第二次锁,直接通过不会阻塞(写错了也能执行),下面的例子就是给一个程序加了两次锁,依旧可以执行成功
public class ThreadDemo1 {public static void main(String[] args) {Object locker =new Object();Thread t1=new Thread(()->{synchronized (locker){synchronized (locker){System.out.println("hi");}}});t1.start();}
}
死锁
死锁(Deadlock)是一个或多个线程因为竞争资源而造成的一种状态,在这种状态下,线程们会无限期地等待一个永远不会发生的条件,从而导致程序无法继续执行。
死锁的经典的三种场景
1.一个线程一把锁,如果是不可重入锁,在加上一把锁,就会出现死锁
2.两个线程,两把锁,第一个线程有A锁,第二个线程有B锁,第一个线程又尝试获取B锁,第二线程尝试获取A锁,就会出现死锁
public class ThreadDemo2 {public static void main(String[] args) {Object A=new Object();Object B=new Object();Thread t1=new Thread(()->{synchronized(A){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (B){System.out.println("t1两把锁");}}});Thread t2=new Thread(()->{synchronized (A){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (B){System.out.println("t2两把锁");}}});t1.start();t2.start();}
}
3.哲学家吃面问题/N个线程M把锁
假设有五位哲学家围坐在一张圆形餐桌旁,每人面前有一碗面,每两个哲学家之间有一只筷子。因为用一只筷子很难吃到面,所以哲学家必须用两只才能吃到面,而他们只能使用自己左右手边的那两只。哲学家们有两种状态:进餐或思考。每当一个哲学家饥饿时,他会试图去拿他左右两边的筷子,但每次只能拿一只。只有当他拿到两只筷子时,才能开始进餐,吃完后需要放下餐叉继续思考。
在这个问题中,筷子是共享资源,而哲学家们对筷子的竞争可能导致死锁的发生。例如,如果每个哲学家都拿起左手边的筷子,等待右手边的餐叉变得可用,而右手边的筷子又被其他哲学家持有,那么就会形成死锁状态,因为每个哲学家都在等待其他哲学家释放资源,而这永远不会发生。
怎么避免死锁
- 设置加锁顺序(最好的方法):线程按照一定的顺序加锁,确保每个线程在请求多个锁时都按照相同的顺序进行。这样可以防止循环等待的情况,从而降低死锁的风险。设置加锁顺序,使得每位哲学家在尝试拿起筷子时都遵循相同的顺序。例如,可以规定所有哲学家都先尝试拿起自己左侧的筷子,然后再拿起右侧的筷子。这样,在任何时候,最多只有一个哲学家能够拿起他左右两侧的筷子,从而避免了死锁的情况
- 避免使用多个锁:尽量将代码设计成只使用一个锁的情况,减少因为多个锁之间的依赖关系导致的死锁4。
- 设置加锁时限(超时重试):在获取锁的时候尝试加一个获取锁的时限,超过时限则放弃操作并释放之前获取到的锁,然后等待一段时间后进行重试。这种方法允许在没有获取锁的时候继续执行其他任务,减少死锁的可能性。
volatile
当一个程序读,一个程序写的时候,此时就容易出现内存可见性问题,volatile就是解决这个问题的,其中一个核心功能就是保证内存可见性
下面的例子创建了两个线程,一个线程不断判断变量的值死循环,另一个等待输入值,使死循环停止,当我们改变flag之后,t1线程并没有结束,这里解释一下原因是编译器发现每次循环都要读取内存,开销太大,于是就把读取内存操作优化为读取寄存器操作,提高效率,就导致写线程做出的修改,读线程感知不到
import java.util.Scanner;class Counter {public int flag;
}public class ThreadDemo {public static void main(String[] args) {Counter counter = new Counter();Thread t1 = new Thread(()->{while(counter.flag==0){//此处为了代码简洁好演示,什么都不做}});Scanner sc = new Scanner(System.in);Thread t2 = new Thread(()->{counter.flag = sc.nextInt();});t1.start();t2.start();}
}
当我们在while循环中加上sleep后发现代码可以执行成功了,因为之前一直循环一秒钟可能循环上百亿次,在循环中加上sleep一秒钟也就执行上百次,大大减少开销
这里最主要的解决方法是加上volatile,告诉编译器这里不需要优化
public volatile int flag=0;//保证内存可见性,禁止指令重排序
相关文章:

线程安全的原因及解决方法
什么是线程安全问题 线程安全问题指的是在多线程编程环境中,由于多个线程共享数据或资源,并且这些线程对共享数据或资源的访问和操作没有正确地同步,导致数据的不一致、脏读、不可重复读、幻读等问题。线程安全问题的出现,通常是…...

微信零钱明细删除了还能恢复吗?图文教程解析
在日常使用微信支付的过程中,查看零钱明细是管理个人财务的一项重要操作。然而,有时候我们可能会不小心删除了这些明细,导致无法追踪资金流动和消费记录。那么,微信零钱明细删除了还能恢复吗?这是许多用户关心的问题。…...

mp4视频太大怎么压缩不影响画质,mp4文件太大怎么变小且清晰度高
在数字化时代,我们常常面临视频文件过大的问题。尤其是mp4格式的视频,文件大小往往令人望而却步。那么,如何在不影响画质的前提下,有效地压缩mp4视频呢?本文将为您揭秘几种简单实用的压缩技巧。 在分享和存储视频时&am…...

【线程同步-2】
同步方法及同步块 接上期三大不安全案例,本期将介绍同步方法和同步块,以期达到安全的目的。 车站买票:加入了synchronized 同步方法 package syn; //不安全的买票 //线程不安全,有负数 public class UnsafeBuyTicket {publi…...

【别再为可视化工具付费了!】财务报表免费制作软件,这款免费可视化工具的功能超乎想象
会计工作中,关键一步就是把那些繁杂的财务数据整理成清晰易懂的财务报表,这就像是把一堆拼图块变成一幅完整的图画。山海鲸可视化这款免费工具,支持实时数据刷新,能够随时随地更新你的财务数据,确保你拿到的永远是最新…...

【HTML入门】第五课 - 加粗和倾斜的字体们
这一小节,我们说一些常用的HTML文本格式化的标签知识。可能你会觉得HTML知识比较零散,有好多标签。没错,就是比较零散,标签比较多。正式这些形形色色的HTML标签们,组成了丰富多彩的网页元素。 但是在刚学习的时候&…...

解决树形表格 第一列中文字没有对齐
二级分类与一级分类的文字没有对齐 <el-table:data"templateStore.hangyeList"style"width: 100%"row-key"id":tree-props"{ children: subData, hasChildren: hasChildren }" ><el-table-column prop"industryCode&quo…...

三级_网络技术_09_IP地址规划技术
1.某企业产品部的IP地址块为211.168.15.192/26,市场部的为211.168.15.160/27,财务部的为211.168.15.128/27,这三个地址块经聚合后的地址为()。 211.168.15.0/25 211.168.15.0/26 211.168.15.128/25 211.168.15.128/26 2.若某大学分配给计…...

力扣1878.矩阵中最大的三个菱形和
力扣1878.矩阵中最大的三个菱形和 斜前缀和 遍历矩阵元素,同时求当前点左下右下两位置的前缀和枚举每个菱形中心,遍历边长 int sum1[101][101];int sum2[101][101];class Solution {public:vector<int> getBiggestThree(vector<vector<in…...

ELB和VPC是云计算领域中的两个术语,通常与Amazon Web Services (AWS)相关联
ELB 和 VPC 是云计算领域中的两个术语,通常与亚马逊云服务(AWS)相关: 1. **ELB (Elastic Load Balancer)**: - 这是AWS提供的一种服务,用于自动分配进入应用程序的流量,以实现高可用性和容错…...

YOLO-World实时开集检测论文阅读
论文:《YOLO-World: Real-Time Open-Vocabulary Object Detection》 代码:https://github.com/AILab-CVC/YOLO-World 1.Abstract 我们介绍了YOLO World,这是一种创新的方法,通过在大规模数据集上进行视觉语言建模和预训练&#…...

LLM - 词向量 Word2vec
1. 词向量是一个词的低维表示,词向量可以反应语言的一些规律,词意相近的词向量之间近乎于平行。 2. 词向量的实现: (1)首先使用滑动窗口来构造数据,一个滑动窗口是指在一段文本中连续出现的几个单词&#x…...

Tileserver GL中glyphs的使用
在Tileserver GL中,glyphs(字形)是用来渲染矢量切片地图中的文本标签的重要组件。它们定义了在地图上显示的字体和文字的具体形状。详细了解glyphs在Tileserver GL中的工作原理,可以帮助我们更好地配置和使用该服务。以下是关于Ti…...

uniapp自动升级
一、创建云服务空间(https://unicloud.dcloud.net.cn) 云空间用于关联需要版本控制升级的项目,如果已拥有云空间则省略此步骤。 二、搭建 uni升级中心 - 后台管理系统(升级中心 uni-upgrade-center - Admin) uni-adm…...

java Pair怎么使用
文章目录 1. 简介2. Pair类的来源3. 如何使用Pair类4. Pair类的实际应用5. Pair类的优点和缺点 1. 简介 什么是Pair Pair是一个通用的数据结构,用于存储一对关联的对象,也就是两个元素。这两个元素可以是任何类型,并且它们之间没有特定的层次…...

数据库doris中的tablet底层解析
在Doris中,tablet(数据片)是数据存储和管理的最小单元。理解tablet的底层原理有助于更好地理解Doris的高可用性、负载均衡和查询优化等特性。 Tablet 的概念 Tablet:Tablet是Doris中用于存储数据的最小物理单元。每个tablet通常对应于一个数据分区和一个分桶组合的子集。…...

江苏高防服务器都有哪些优势?
江苏高防服务器所针对的应用群体是不同的,高防服务器与普通服务器的应用效果和功能上是有着很大的差别,所以企业与用户在进行挑选高防服务器时,会更加看重服务器的质量与服务效果,本文就来聊一下江苏高防服务器的优势有哪些吧&…...

Pytest单元测试系列[v1.0.0][Pytest基础]
Pytest安装与配置 和Unittest一样,Pytest是另一个Python语言的单元测试框架,与Unittest相比它的测试用例更加容易编写、运行方式更加灵活、报错信息更加清晰、断言写法更简洁并且它可以运行有unittest和nose编写的测试用例。 Pytest 安装 启动命令行&…...

C/C++服务器基础(网络、协议、数据库)
Socket Socket是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。它可以看成是两个网络应用程序进行通信时,各自通信连接中的端点。Socket上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用…...

Mysql系列-Binlog主从同步
原文链接:https://zhuanlan.zhihu.com/p/669450627 一、主从同步概述 mysql主从同步,即MySQL Replication,可以实现将数据从一台数据库服务器同步到多台数据库服务器。MySQL数据库自带主 从同步功能,经过配置,可以实现基于库、表…...

java设计模式(六)——原型模式
一、模式介绍 原型模式: 创建型模式之一,就是基于原型创建对象,也就是一个对象的产生可以不由零起步, 直接从一个已经具备一定雏形的对象克隆,然后再修改为所需要的对象。节约创建对象时间。 使用场景 如果对象创建成本比较大,例如某个对象里面的数据需要访问数据库才能…...

arm (exti中断)
src/key_it.c 1 #include "key_it.h"2 3 //按键1中断配置4 void key1_config()5 {6 //RCC章节7 //1:使能gpio f8 RCC->MP_AHB4ENSETR | (0x1<<5);9 //因为exti和gic属于芯片内部 所以无需使能10 11 //GPIO章节12 //1:将…...

触摸屏虚拟键盘组件 jQuery Virtual Keyboard使用 自定义键盘
如何在触摸设备上为输入域添加虚拟键盘? 一个插件可以解决这个问题,关键还支持高度自定义(git地址): GitHub - Mottie/Keyboard: Virtual Keyboard using jQuery ~ 官网地址:Virtual Keyboard 使用步骤&…...

面试题07-09
知道了 InnoDB 的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。再例如,用非单调的字段作为主键在 InnoDB 中不是个好主意,因为 InnoD…...

MySQL之binlog日志
原文链接:https://zhuanlan.zhihu.com/p/697078870 目录: binlog 是什么binlog 配置和查看binlog 的类型binlog 如何恢复数据binlog 是逻辑日志还是物理日志binlog 作用 注意:以下所有的操作都在 MySQL 8.0 版本实现。 1、binlog 是什么 …...

【大数据】什么是数据湖?一文揭示数据湖的本质
很多人跟我一样,对于数据湖充满好奇,也许还读了不少数据湖文章,但无论别人怎么说,你还是会觉得难以把握数据湖的本质。 有些人会望文生义说,数据湖嘛,就是什么东西都可以往里面扔,特别是对非结构…...

CSS【详解】文本相关样式(含 font 系列,文本排版,文本装饰,分散对齐,渐变色文本等)
文本风格 font-style font-style:italic 值描述normal默认值。浏览器显示一个标准的字体样式。italic加载对应字体的斜体字体文件,若找不到斜体字体文件,则进行物理上的倾斜。 标签默认font-style:italicoblique浏览器会显示一个倾斜的字体样式。 文本粗…...

加油卡APP系统开发,优惠加油收益
目前,汽车已经成为了不可或缺的出行工具,汽车加油更是成为了家家户户要做的事。不过随着油价的波动,车主急需能够进行优惠加油的渠道,因此,加油卡APP成为了大众汽车加油新的选择方式,用户在下载APP后即可享…...

el-scrollbar实现自动滚动到底部(AI聊天)
目录 项目背景 实现步骤 实现代码 完整示例代码 项目背景 chatGPT聊天消息展示滚动面板,每次用户输入提问内容或者ai进行流式回答时需要不断的滚动到底部确保展示最新的消息。 实现步骤 采用element ui 的el-scrollbar作为聊天消息展示组件。 通过操作dom来实…...

开源去除背景的项目:rembg 安装和部署
下载colne项目代码 git clone https://github.com/danielgatis/rembg.git安装依赖 pip install rembg pip install click pip install filetype pip install watchdog pip install aiohttp pip install gradio pip install asyncer测试使用 rembg i 照片.jpg zhaopian.jpg照…...