【C#】知识点实践序列之Lock简单解决并发引起数据重复问题
欢迎来到《小5讲堂之知识点实践序列》文章,大家好,我是全栈小5。
这是2024年第3篇文章,此篇文章是C#知识点实践序列文章,博主能力有限,理解水平有限,若有不对之处望指正!
本篇在Lock锁定代码块基础上进行简单解决并发问题,确保不会出现重复数据。

目录
- 前言
- 实践场景
- 用户编码重复
- 效果
- 代码
- 用户编码唯一
- 效果
- 代码
- 并发基本概念

前言
前两篇文章已经回顾基本概念一级Lock锁定代码块的实践例子,以及简单了解了多线程的基本信息。
实践场景
有一个用户注册的功能,通过简单并发测试,在不进行索引等情况下,对比加锁和不加锁,用户表重复记录情况
用户编码重复
在并发情况下,如果方法代码和数据库没有做唯一处理,那么进行用户注册时,用户编码重复概率是很大的。
下面是逻辑是,设置3个异步方法模拟3个并发访问,他们之间就极有可能是同时执行同一个方法,用户编码就可能会重复。
效果

- 重复数据
从下图可以知道,GZ0008、GZ0018、GZ00021,这就会出现重复了,相对于用户编码就不是唯一,也就无法满足实际场景。

代码
namespace XxxData
{/// <summary>/// 解决数据重复/// </summary>public partial class LockUser : Form{public LockUser(){InitializeComponent();CheckForIllegalCrossThreadCalls = false;}private void Form1_Load(object sender, EventArgs e){}int userCodeIndex = 0;private void TargetData(){userCodeIndex += 1;txtInfo.AppendText($"GZ{userCodeIndex.ToString().PadLeft(5, '0')}\r\n");}private void btnA_Click(object sender, EventArgs e){// ===模拟并发===// 用户并发a区域Task.Run(() =>{for(int i = 0; i < 10; i++){TargetData();Thread.Sleep(10);}});// 用户并发b区域Task.Run(() =>{for (int i = 0; i < 10; i++){TargetData();Thread.Sleep(10);}});// 用户并发c区域Task.Run(() =>{for (int i = 0; i < 10; i++){TargetData();Thread.Sleep(10);}});}}
}
用户编码唯一
基于用户编码唯一原则,那么解决的方法有很多,这里我们通过锁定代码块的方式来解决,也就是同步机制来解决。
同步机制的最大特点就是,即使有多个请求同一时间调用同一个方法,它也会遵循一个一个执行完,从而用户编码也只会顺序叠加。
效果
- 方法部分锁
int userCodeIndex = 0;
private void TargetData(int num)
{txtInfo.AppendText($"用户【{num}】进入方法,等待添加!\r\n");lock (this){userCodeIndex += 1;txtInfo.AppendText($"GZ{userCodeIndex.ToString().PadLeft(5, '0')}\r\n\r\n");}
}

- 方法全部锁
int userCodeIndex = 0;
private void TargetData(int num)
{lock (this){txtInfo.AppendText($"用户【{num}】进入方法,等待添加!\r\n");userCodeIndex += 1;txtInfo.AppendText($"GZ{userCodeIndex.ToString().PadLeft(5, '0')}\r\n\r\n");}
}

代码
namespace XxxData
{/// <summary>/// 解决数据重复/// </summary>public partial class LockUser : Form{public LockUser(){InitializeComponent();CheckForIllegalCrossThreadCalls = false;}private void Form1_Load(object sender, EventArgs e){}int userCodeIndex = 0;private void TargetData(int num){lock (this){txtInfo.AppendText($"用户【{num}】进入方法,等待添加!\r\n");userCodeIndex += 1;txtInfo.AppendText($"GZ{userCodeIndex.ToString().PadLeft(5, '0')}\r\n\r\n");}}private void btnA_Click(object sender, EventArgs e){// ===模拟并发===// 用户并发a区域Task.Run(() =>{for(int i = 0; i < 10; i++){TargetData(i + 1);Thread.Sleep(10);}});// 用户并发b区域Task.Run(() =>{for (int i = 10; i < 20; i++){TargetData(i + 1);Thread.Sleep(10);}});// 用户并发c区域Task.Run(() =>{for (int i = 20; i < 30; i++){TargetData(i + 1);Thread.Sleep(10);}});}}
}
并发基本概念
C# 并发与方法和 API 接口请求之间有一些关联和区别:
1.并发方法调用:在 C# 中,可以使用多线程或任务并发地调用方法。这种方式适用于需要同时执行多个方法并获得结果的场景。通过多线程或任务的并发,可以提高系统的响应能力和吞吐量。
2.API 接口请求:API 接口请求是通过网络协议发送请求,获取相应的资源或执行操作。在 C# 中,可以使用异步或并发技术来发起多个 API 请求,以提高性能和并发处理能力。常见的方式包括使用异步/等待模式、多线程或任务并发等。
3.并发控制:并发方法调用和 API 接口请求都需要考虑并发控制的问题。在多个线程或任务同时访问共享资源时,可能会出现竞态条件等并发问题。C# 中提供了锁、互斥体、信号量等机制来实现并发控制,以确保共享资源的安全访问。
总结:温故而知新,不同阶段重温知识点,会有不一样的认识和理解,博主将巩固一遍知识点,并以实践方式和大家分享,若能有所帮助和收获,这将是博主最大的创作动力和荣幸。也期待认识更多优秀新老博主。
相关文章:
【C#】知识点实践序列之Lock简单解决并发引起数据重复问题
欢迎来到《小5讲堂之知识点实践序列》文章,大家好,我是全栈小5。 这是2024年第3篇文章,此篇文章是C#知识点实践序列文章,博主能力有限,理解水平有限,若有不对之处望指正! 本篇在Lock锁定代码块基…...
NLP基础——TF-IDF
TF-IDF TF-IDF全称为“Term Frequency-Inverse Document Frequency”,是一种用于信息检索与文本挖掘的常用加权技术。该方法用于评估一个词语(word)对于一个文件集(document)或一个语料库中的其中一份文件的重要程度。…...
kubernetes(四)
文章目录 1. 持久化存储1.1 HostPath1.2 NFS1.3 PV和PVC 1. 持久化存储 1.1 HostPath hostpath:多个容器共享数据,不能跨宿主机,如果宿主机挂了,在其他宿主机上起pod,那么之前的数据就没有了 spec:nodeName: 10.0.0…...
安科瑞变电站综合自动化系统在青岛海洋科技园应用——安科瑞 顾烊宇
摘 要:变电站综合自动化系统是将变电站内的二次设备经过功能的组合和优化设计,利用先进的计算机技术、通信技术、信号处理技术,实现对全变电站的主要设备和输、配电线路的自动监视、测量、控制、保护、并与上级调度通信的综合性自动化功能。 …...
紫光展锐5G扬帆出海 | 欧洲积极拥抱更多5G选择
和我国一样,欧洲不少国家也在2019年进入5G商用元年:英国在2019年5月推出了5G商用服务,该国最大的移动运营商EE(Everything Everywhere)最先商用5G;德国在2019年年中推出5G商用服务,德国电信、沃达丰和 Telefonica是首批…...
Open3D聚类算法
按照官网的例子使用聚类,发现结果是全黑的。 经过多次测试发现 eps3.3, min_points1这里是关键 min_points必须等于1否则无效果 import time import open3d as o3d; import numpy as np; import matplotlib.pyplot as plt#坐标 mesh_coord_frame o3d.geometry.Tria…...
swing快速入门(三十九)进度对话框
🎁注释很详细,直接上代码 🧧新增内容 🧨1.模拟耗时操作 🧨2.使用计时器更新进度对话框 🎀源码: package swing31_40;import javax.swing.*; import java.awt.event.ActionEvent; import java.aw…...
Oracle-存储过程
简介 存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,它大大提高了SQL语句的功能和灵活性。存储过程编译后存储在数据库中,所以执行存储过程比执行存储过程中封装的SQL语句更有效率。 语法 存储过程: 一组为了完成某种特定功能的sql语句…...
L1-085:试试手气
我们知道一个骰子有 6 个面,分别刻了 1 到 6 个点。下面给你 6 个骰子的初始状态,即它们朝上一面的点数,让你一把抓起摇出另一套结果。假设你摇骰子的手段特别精妙,每次摇出的结果都满足以下两个条件: 1、每个骰子摇出…...
nginx+keepalived实现七层负载
目录 一、部署nginx01、nginx02 二、keepalived配置(抢占模式、master- backup模式) 三、测试 四、非抢占模式(backup-backup模式) nginx01 11.0.1.31nginx0211.0.1.32虚拟IP(VIP)11.0.1.30 一、部署ngin…...
机器人制作开源方案 | 智能盲道除雪小车
作者:汪荣顺 李明旭 马晓乐 吴泽俊 李以陈 单位:江汉大学 指导老师:张朝刚 张会利 本文论述了一种新型智能盲道除雪小车的设计与研发。由于目前的除雪设备集中在公路、城市道路、机场路面、高速公路等领域,但对于街道等路况的研…...
Mypy: 把静态类型检查带给Python
之前我们介绍过,Python作为一门动态语言,为人诟病的缺点之一,就是难以像java那样,支持静态类型检查,这样会把一些错误带到运行中(如果你不进行单元测试的话)。 不过,随着type hint的推开,实际上现在Python已经有了比较充分的静态类型检查。这一章我们先介绍其它Lint工…...
【心得杂记】简单聊聊限制高速面阵相机性能的因素
研究了限制高速面阵相机发展的因素,感觉就是揭开了薄雾面纱之后的复杂。 个人观点,不保证全对~ 欢迎讨论~ 高速相机是一个整体,涉及的各个零部件和模组很多,每个环节都会影响相机指标的提高。 高速相机主要包括的核心部件有&#…...
金蝶Apusic应用服务器 loadTree JNDI注入漏洞
产品介绍 金蝶Apusic是一款企业级应用服务器,支持Java EE技术,适用于各种商业环境。 漏洞概述 由于金蝶Apusic应用服务器权限验证不当,使用较低JDK版本,导致攻击者可以向loadTree接口执行JNDI注入,远程加载恶意类&a…...
计算机毕业设计 基于SpringBoot的公司资产网站的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
如何获取时间戳?
获取现在的时间0时0秒 一、JavasCRIPT时间转时间戳 JavaScript获得时间戳的方法有五种,后四种都是通过实例化时间对象new Date() 来进一步获取当前的时间戳,JavaScript处理时间主要使用时间对象Date Date.now()可以获得当前的时间戳: con…...
Vue页面传值:Props属性与$emit事件的应用介绍
一、vue页面传值 在Vue页面中传值有多种方式,简单介绍以下两种 通过props属性传递值:父组件在子组件上定义props属性,子组件通过props接收父组件传递的值。通过$emit触发事件传递值:子组件通过$emit方法触发一个自定义事件&#…...
【mars3d】new mars3d.layer.GeoJsonLayer(实现环状面应该怎么传data
问题:【mars3d】new mars3d.layer.GeoJsonLayer(实现环状面应该怎么传data 解决方案: 1.在示例中修改showDraw()方法的data数据,实现以下环状面效果 2.示例链接: 功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 export f…...
Websocket实时更新商品信息
产品展示页面中第一次通过接口去获取数据库的列表数据 /// <summary> /// 获取指定的商品目录 /// </summary> /// <param name"pageSize"></param> /// <param name"pageIndex"></param> /// <param name"i…...
数据结构第六弹---带头双向循环链表
双向循环链表 1、带头双向循环链表概念2、带头双向循环链表的优势3、带头双向循环链表的实现3.1、头文件包含和结构定义3.2、创建新结点3.3、打印3.4、初始化3.5、销毁3.6、尾插3.7、头插3.8、头删3.9、尾删3.10、查找3.11、在pos之前插入3.12、删除pos位置3.13、判断是否为空3…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
