【C#】知识点实践序列之Lock的锁定代码块

news2025/1/20 13:16:40

大家好,我是全栈小5,欢迎来到《小5讲堂之知识点实践序列》文章。
2023年第1篇文章,此篇文章是C#知识点实践序列之Lock知识点,博主能力有限,理解水平有限,若有不对之处望指正!
本篇验证Lock锁定代码执行情况,锁定外上下代码和锁定区域的代码执行情况。

在这里插入图片描述

目录

  • 基本概念
    • 锁流程
    • 注意点
  • 实践场景
    • 锁定代码块
      • 效果
      • 代码
  • 疑问解答
    • 消息队列
  • 常见报错

在这里插入图片描述

基本概念

在 C# 中,锁(lock)是一种用于实现多线程同步的机制。
它可以用来确保在任何给定时间只有一个线程可以访问被锁定的代码块,以避免数据竞争和并发访问的问题。

  • 流程图
    在这里插入图片描述

锁流程

1、创建一个共享资源,在多个线程之间需要安全地访问该资源。
2、使用 lock 关键字来定义一个临界区域(即需要同步的代码段),将要访问共享资源的代码放置在该临界区域内。
3、在进入临界区域之前,线程会尝试获取锁。如果锁已经被其他线程持有,则当前线程会阻塞,直到锁释放。
4、当线程得到锁之后,它可以安全地访问临界区域内的代码,执行完毕后释放锁,以便其他线程可以继续执行。

注意点

1、锁定的对象应该是所有线程都可以访问到的共享对象,常见的做法是使用一个私有变量作为锁对象。
2、锁的范围应该尽量小,只锁定必要的代码区域,以避免不必要的线程阻塞。
3、锁的使用应遵循一致的原则,即在所有访问共享资源的地方都要使用同一个锁对象。这样可以确保所有线程都按顺序获取锁,避免死锁的发生。

实践场景

通过实际例子来验证知识点的基本概念,这样能够加深对知识点的理解,只有对知识点的理解足够深,才能更好的编写高质量代码和实现高效逻辑代码。

锁定代码块

以下是展示代码块被锁定,但方法内其他代码仍然按顺序直接执行。
比如同时进行操作点击用户a、用户b、用户c、三个按钮,然后都会调用同一个方法,方法内只锁定统计数量,并且锁定3秒,其他代码没有锁定。

效果

从以下界面效果可以知道,没有被锁定代码是会先执行,然后锁定区域先执行用户a,然后锁定3秒后,再执行用户b,依此类推。
在这里插入图片描述

代码

namespace XxxData
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            CheckForIllegalCrossThreadCalls = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private int visitorCount = 0;
        private void TargetData(string user)
        {
            txtInfo.AppendText($"{user}{DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss")}\r\n");

            lock (this)
            {
                visitorCount += 1;
                lbVisitorCount.Text = $"访问用户数:{visitorCount}";

                Thread.Sleep(3 * 1000);
                txtInfo.AppendText($"{user}执行完毕,{DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss")}\r\n");
            }
        }

        private void btnA_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                TargetData("用户a");
            });
        }

        private void btnB_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                TargetData("用户b");
            });
        }

        private void btnC_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                TargetData("用户c");
            });
        }
    }
}

疑问解答

消息队列

Lock锁定代码块是否属于一种消息队列,多个访问同时进来,只能排队一个一个访问。A执行完Lock方法内的代码才允许下一个执行进来。

并不是,C# 的 lock 关键字并不是一种消息队列。它是一种线程同步机制,用于在多线程访问共享资源时确保同一时间只有一个线程可以进入被锁定的代码块。
当多个线程同时访问含有 lock 代码块的区域时,只有一个线程能够获取到锁,进入临界区域执行代码,其余线程则被阻塞并排队等待锁的释放。一旦获取到锁的线程执行完毕,释放锁后,等待队列中的下一个线程会获取锁,依此类推。
这种机制确保了同一时间只有一个线程能够访问共享资源,避免了数据竞争和并发访问的问题。但请注意,锁并不提供先后顺序的保证,即不保证等待队列中线程按照某种特定的顺序获取锁。
消息队列是另一种机制,用于线程(或进程)间的通信。它允许将消息从一个线程发送到另一个线程,接收线程可以按照消息的先后顺序处理消息,实现异步通信和任务分发。而 lock 关键字只是提供了互斥访问的能力,并不涉及消息的发送和接收。

常见报错

##跨线程访问
由于label控件是在主线程,在Task线程默认是无法访问在这里插入图片描述
解决方法,在异步方法前面增加如下代码

CheckForIllegalCrossThreadCalls = false;

总结:温故而知新,不同阶段重温知识点,会有不一样的认识和理解,博主将巩固一遍知识点,并以实践方式和大家分享,若能有所帮助和收获,这将是博主最大的创作动力和荣幸。也期待认识更多优秀新老博主。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1347987.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spark精讲】一文讲透Spark宽窄依赖的区别

宽依赖窄依赖的区别 窄依赖:RDD 之间分区是一一对应的宽依赖:发生shuffle,多对多的关系 宽依赖是子RDD的一个分区依赖了父RDD的多个分区父RDD的一个分区的数据,分别流入到子RDD的不同分区特例:cartesian算子对应的Car…

C#线程基础(线程启动和停止)

目录 一、关于线程 二、示例 三、生成效果 一、关于线程 在使用多线程前要先引用命名空间System.Threading,引用命名空间后就可以在需要的地方方便地创建并使用线程。 创建线程对象的构造方法中使用了ThreadStart()委托,当线程开始执行时&#xff0c…

【C++对于C语言的扩充】C++与C语言的联系,命名空间、C++中的输入输出以及缺省参数

文章目录 🚀前言🚀C有何过C之处?🚀C中的关键字🚀命名空间✈️为什么要引入命名空间?✈️命名空间的定义✈️如何使用命名空间中的内容呢? 🚀C中的输入和输出✈️C标准库的命名空间✈…

VStudio2022导出Qt项目在Linux的Qtcreator中运行修复错误记录

公司项目中的代码在VStudio2022中编写,交给我需要移植Linux的Qtcreator中,记录一下移植过程中的遇到的坑,按照错误顺序由高到低记录一下,边尝试边解决边记录,写作方面没有逻辑,每个人项目环境不一样&#x…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取相机当前数据吞吐量(C#)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK里函数来获取相机当前数据吞吐量(C#) Baumer工业相机Baumer工业相机的数据吞吐量的技术背景CameraExplorer如何查看相机吞吐量信息在NEOAPI SDK里通过函数获取相机接口吞吐量 Baumer工业相机通过NEOAPISDK获…

PHP与Angular详细对比 帮助你选择合适的项目技术

开发可有效扩展并提供诺克斯堡级安全性的Web应用程序和网站是每个开发人员的梦想。而使用这样的产品是每个用户的愿望。因此,为您的项目选择最合适和可靠的技术非常关键。 虽然PHP和Angular是完全不同的技术——PHP与JavaScript是一个更恰当的比较——但它们都广泛…

【JavaFX】JDK11 基于Gson、hutool、Jackson持久化存储实体类数据的解决方案 (读取、追加、去重、写入json对象)

文章目录 开发环境效果前言一、Gson是什么?二、使用步骤1.引入依赖2.创建实体类创建 JsonFileService类创建JsonFileService的实现类 JsonFileServiceImpl三、实现效果开发环境 JDK11IDEA 2023.3Gson、hutool、JacksonJavaFX 11效果 前言 使用JDK1

浅聊配置化-要不要实现动态表单

1、配置化的原则 配置化是一种抽象,把事物分成2类:不变的,可变的。 如果事物都是可变的,是无法实现配置化的。 配置化的根本在于找到不变的事物,基于不变的事物进行可变事物的配置。 所以,认为一切皆可…

Deeplearning4j 实战 (22):基于DSSM的语义匹配建模

Deeplearning4j 实战 (22):基于DSSM的语义匹配建模 Eclipse Deeplearning4j GitChat课程:Deeplearning4j 快速入门_专栏 Eclipse Deeplearning4j 系列博客:万宫玺的专栏_wangongxi_CSDN博客 Eclipse Deeplearning4j G…

基于Spring Boot的美妆分享系统:打造个性化推荐、互动社区与智能决策

基于Spring Boot的美妆分享系统:打造个性化推荐、互动社区与智能决策 1. 项目介绍2. 管理员功能2.1 美妆管理2.2 页面管理2.3 链接管理2.4 评论管理2.5 用户管理2.6 公告管理 3. 用户功能3.1 登录注册3.2 分享商品3.3 问答3.4 我的分享3.5 我的收藏夹 4. 创新点4.1 …

【基础】【Python网络爬虫】【3.chrome 开发者工具】(详细笔记)

Python网络爬虫基础 chrome 开发者工具元素面板(Elements)控制台面板(Console)资源面板(Source)网络面板(Network)工具栏Requests Table详情 chrome 开发者工具 ​ 当我们爬取不同的网站是&…

「微服务」Saga 模式 如何使用微服务实现业务事务-第二部分

在上一篇文章中,我们看到了实现分布式事务的一些挑战,以及如何使用Event / Choreography方法实现Saga的模式。在本文中,我们将讨论如何通过使用另一种类型的Saga实现(称为Command或Orchestration)来解决一些问题&#…

win10系统请将eNSP相关应用程序添加到windows firewall的允许程序列表,并允许其在公用网络上运行!的解决办法

很多学习网络的小伙伴,在下载安装eNSP后,打开程序跳出:请将eNSP相关应用程序添加到windows firewall的允许程序列表,并允许其在公用网络上运行! 是不是挺闹心的! 其实,原因是很简单,就是win10系统防火墙访…

Linux中安装了openjdk后jps command not found

一、问题场景 在Linux中用yum安装了openjdk-17,也在.bashrc中配置了环境变量JAVA_HOME以及bin目录的PATH。 但是在运行jps命令时依然报错找不到命令 二、原因分析 进入到$JAVA_HOME/bin目录查看,发现只有寥寥几个命令,压根没有jps命令&…

微信小程序发送模板消息-详解【有图】

前言 在发送模板消息之前我们要首先搞清楚微信小程序的逻辑是什么,这只是前端的一个demo实现,建议大家在后端处理,前端具体实现:如下图 1.获取小程序Id和密钥 我们注册完微信小程序后,可以在开发设置中看到以下内容&a…

4.35 构建onnx结构模型-Layernorm

前言 构建onnx方式通常有两种: 1、通过代码转换成onnx结构,比如pytorch —> onnx 2、通过onnx 自定义结点,图,生成onnx结构 本文主要是简单学习和使用两种不同onnx结构, 下面以 Layernorm 结点进行分析 方式 方法…

LAYABOX:2024新年寄语

2024新年寄语 过去的一年,尽管许多行业面临严峻挑战和发展压力,小游戏领域却逆势上扬,年产值首次突破400亿元大关,众多优质小游戏企业收获颇丰。 对此,祝福大家,2024一定更好! 过去的一年&#…

Good Bye 2023

Good Bye 2023 Good Bye 2023 A. 2023 题意:序列a中所有数的乘积应为2023,现在给出序列中的n个数,找到剩下的k个数并输出,报告不可能。 思路:把所有已知的数字乘起来,判断是否整除2023,不够…

掌握C++11标准库(STL):理解STL的核心概念

深入探索C11标准库STL:新特性和优化技巧 一、前言二、容器简介三、迭代器简介四、map与unordered_map(红黑树VS哈希表)4.1、map和unordered_map的差别4.2、优缺点以及适用处4.3、小结 五、总结 一、前言 STL定义了强大的、基于模板的、可复用…

海康visionmaster-渲染控件:渲染控件加载本地图像的方法

描述 环境:VM4.0.0 VS2015 及以上 现象:渲染控件如何显示本地图像? 解答 思路:在 2.3.1 中,可以通过绑定流程或者模块来显示图像和渲染效果。因此,第一步, 可以使用在 VM 软件平台中给图像源模…