【C#】知识点实践序列之Lock的输出多线程信息

大家好,我是全栈小5,欢迎来到《小5讲堂之知识点实践序列》文章。
2023年第2篇文章,此篇文章是C#知识点实践序列之Lock知识点,博主能力有限,理解水平有限,若有不对之处望指正!
本篇在Lock锁定代码块输出多线程信息,用于判断是否是同一个线程还是不同线程。

在这里插入图片描述

目录

  • 前言
  • 实践场景
    • 线程
    • 效果
    • 代码
  • 疑问解答
    • 线程调度

在这里插入图片描述

前言

上篇文章已经回顾基本概念,并验证了Lock锁定代码块多线程访问效果。

实践场景

同样是执行三个方法,三个Task异步方法调用同一个方法。

线程

在 C# 中,线程是用于执行代码的基本执行单元。线程可以让程序在多个任务之间切换执行,以实现并发和并行处理。
线程基本信息,线程ID、线程名称、线程状态、是否为后台线程、是否为线程池线程。

// 获取当前线程信息
Thread currentThread = Thread.CurrentThread;// 输出线程信息
Console.WriteLine("线程 ID: {0}", currentThread.ManagedThreadId);
Console.WriteLine("线程名称: {0}", currentThread.Name);
Console.WriteLine("线程状态: {0}", currentThread.ThreadState);
Console.WriteLine("是否为后台线程: {0}", currentThread.IsBackground);
Console.WriteLine("是否为线程池线程: {0}", currentThread.IsThreadPoolThread);Console.ReadLine();

效果

从下面可以知道,如果在短时间内操作点击完按钮用户a、用户b、用户c,那么它的线程ID是不同的。
如果是逐个点击,那么它的线程ID又是一样的。

  • 快速点
    在这里插入图片描述
  • 逐个点
    在这里插入图片描述

代码

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){Thread.Sleep(3 * 1000);// 获取和输出当前线程信息Thread currentThread = Thread.CurrentThread;txtInfo.AppendText($"线程 ID: {currentThread.ManagedThreadId},");txtInfo.AppendText($"线程名称: {currentThread.Name},");txtInfo.AppendText($"线程状态: {currentThread.ThreadState},");txtInfo.AppendText($"是否为后台线程: {currentThread.IsBackground},");txtInfo.AppendText($"是否为线程池线程: {currentThread.IsThreadPoolThread}\r\n");visitorCount += 1;lbVisitorCount.Text = $"访问用户数:{visitorCount}";txtInfo.AppendText($"{user}执行完毕,{DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss")}\r\n\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");});}}
}

疑问解答

C# 为什么不同Task发起调用的到同一个Lock区域的线程ID是一样的,有些不同线程ID又不同

线程调度

在 C# 中,多线程程序中的线程调度是由操作系统来处理的,所以无法对线程的调度行为进行精确控制。这就导致了在多个 Task 中进行 lock 调用时,无法保证每个 Task 所在的线程的执行先后顺序是固定不变的。

当多个 Task 同时竞争同一个锁时,可能会有多个线程同时尝试获取锁。当其中一个线程获得锁时,其他线程会被阻塞,直到获得锁的线程释放锁资源。在获得锁之前,这些阻塞的线程是处于等待状态,并且可以从操作系统的线程池中进行调度分配。

由于线程调度的不确定性,操作系统可能会在调度线程时将某个 Task 所在的线程与其他线程互相切换执行。这就导致了在不同的执行时间点上,同一个 Lock 区域中的线程 ID 可能是相同的,也可能是不同的。

要注意的是,线程 ID 并不是唯一标识一个线程的属性。线程 ID 只是代表线程的一个标识符,它可以在不同的时间点上被复用。所以,当多个 Task 同时竞争同一个锁时,虽然线程 ID 可能是不同的,但实际上代表不同 Task 所在线程的执行上下文和状态是不同的。

总结起来,无法确定不同 Task 中获取同一个锁的线程 ID 是否相同,这是由于多线程调度的不确定性所导致的。在编写多线程程序时,应该关注线程同步的正确性而不是具体的线程 ID

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

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

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

相关文章

【python_数据分组】

对excel按照标签进行分组,例如按照“开票主体和对方公司”进行分组,并获取对应的明细。 表格如下: def main(excel_data):result {}for d in excel_data:if str(d[0])str(d[1]) in result:result[str(d[0])str(d[1])].append([d[0],d[1],…

web component - 使用HTML Templates和Shadow DOM构建现代UI组件

Web Component是一种用于构建可重用的UI组件的技术。它使用标准化的浏览器API,包括Custom Elements、Shadow DOM和HTML Templates来实现组件化开发方式。这些API都是现代浏览器原生支持的,因此不需要引入第三方库或框架即可使用。 在这篇博客中&#xf…

第6课 用window API捕获麦克风数据并加入队列备用

今天是2024年1月1日,新年的第一缕阳光已经普照大地,祝愿看到这篇文章的所有程序员或程序爱好者都能在新的一年里持之以恒,事业有成。 今天也是我加入CSDN的第4100天,但回过头看一看,这么长的时间也没有在CSDN写下几篇…

SpringCloud-高级篇(九)

(1)Seata高可用 我们学习了Seata的各种用法了,Seata的服务是单节点部署的,这个服务如果挂了,整个事务都没有办法完了,下面我们学习Seata的高可用的知识。 实现高可用,还是比较简单,…

QT上位机开发(抽奖软件)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 用抽奖软件抽奖,是一种很常见的抽奖方式。特别是写这篇文章的时候,正好处于2023年12月31日,也是一年中最后一天…

【华为机试】2023年真题B卷(python)-喊七的次数重排

一、题目 题目描述: 喊7是一个传统的聚会游戏,N个人围成一圈,按顺时针从1到N编号。 编号为1的人从1开始喊数,下一个人喊的数字为上一个人的数字加1,但是当将要喊出来的数字是7的倍数或者数字本身含有7的话,…

新手快速上手掌握基础排序<二>快速排序快速入门

目录 引言 一:快速排序qsort的简介 1.qsort是一个库函数 2.库函数的查询了解方法 3.qsort的具体使用方法 4.qsort函数使用的一些注意点 5.qsort函数的特点 6.代码实现 (1)整数数组的快速排序 (2)结构体的快速排序(学…

使用.Net nanoFramework 驱动ESP32的OLED显示屏

本文介绍如何使用.Net nanoFramework 驱动ESP32的OLED显示屏。我们将会从最基础的部分开始,逐步深入,让你能够理解并实现整个过程。无论你是初学者还是有一定经验的开发者,这篇文章都会对你有所帮助。 1. 硬件准备 1.1 ESP32开发板 这里我们…

PyTorch的Tensor(张量)

一、Tensor概念 什么是张量? 张量是一个多维数组,它是标量、向量、矩阵的高维拓展 Tensor与Variable Variable是torch.autograd中的数据类型,主要用于封装Tensor,进行自动求导。 data: 被包装的Tensorgrad: data的梯度&…

基于OpenCv的车道检测

项目背景和步骤 车道检测是自动驾驶领域不可或缺的一环 具体步骤如下: 一、将图像灰度化,并进行适度的高斯滤波,剔除干扰 二、利用Canny边缘检测,检测出车道和其它物体的边缘 三、使用ROI区域截取,截取需要的部分&a…

AI与数字化映像:颜值开端,功能至上_光点科技

在人工智能的浪潮中,AI数字人的兴起正成为一个不可忽视的现象。随着ChatGPT等生成式AI算法的进步,AIGC(人工智能生成内容)的应用呈现出爆发性增长,不仅在技术圈引起广泛关注,也为元宇宙及其相关产业链带来了…

小白入门java基础-反射详解

一:介绍 Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的高级程序设计语言。 Java 可运行于多个平台,如 Windows, Mac OS 及其他多种 UNIX 版本的系统。Java语言编写的程序,在一次编译后,可以在多个系统平台上运行。 主…

Spring Boot笔记1

1. SpringBoot简介 1.1. 原有Spring优缺点分析 1.1.1. Spring的优点分析 Spring是Java企业版(Java Enterprise Edition,javeEE)的轻量级代替品。无需开发重量级的Enterprise JavaBean(EJB),Spring为企业…

Bmp2Png是什么工具?好用吗?

Bmp2Png是什么工具?好用吗? 批量BMP图片转为PNG透明图片,去掉BMP黑色背景,压缩导出png图片V1.1前段时间上传了一款bmp转png并去黑底的demo软件,非常受欢迎, 上一版本地址:批量BMP图片转为PNG…

计算机网络 (期末救命版)

文章目录 Ⅰ 网络概述1. 互联网概述与组成2. 计算机网络的类别3. 计算机网络的性能指标4. 计算机网络体系结构 Ⅱ 物理层1. 物理层的任务2. 信道复用技术 Ⅲ 数据链路层1. 点对点信道2. 基本问题3. 点对点协议 PPP4. 使用广播信道的数据链路层 Ⅳ 网络层1. 网络层的服务2. 网际…

解算人生--写于2023跨年之夜

最近买了一本书,书名叫《计算》 读了部分内容,虽然理解上还需要再下下功夫,但是直观的感觉冲击还是挺大的,最明显的就是表面与本质的把握。大家可能都有这样一种感觉,初步涉足某一领域时,开始我们都会被大量…

github使用技巧(经验篇)

相关经验 指定代码范围并高亮显示 例如,指定nn_ops.py文件2612-L2686行的代码:https://github.com/tensorflow/tensorflow/blob/v2.14.0/tensorflow/python/ops/nn_ops.py#L2612-L2686 FAQ Q:github网页打不开? 【github加载不…

WeNet语音识别调用通义千问

WeNet语音识别调用通义千问 WeNet语音识别对通义千问(Qwen-72B-Chat Bot)调用,首先通过WeNet将用户的语音输入转录为文本,然后将此文本输入通用问答模型以获取答案。 本人原创作品,体验一下 连续对话 WeNet语音识别…

一起玩儿物联网人工智能小车(ESP32)——22. 用ESP32的LED PWM控制器给TT马达调速(C MicroPython)

新年快乐! 2024,我们一起玩儿! 摘要:本文主要介绍如何使用Mixly实现PWM波形的输出。 下面就先用Mixly实现PWM波形的输出。首先打开Mixly软件,这次还是先使用C语言来实现。如果你有示波器,或者逻辑分析仪&a…

基于SSM的牙科诊所管理系统

基于SSM的牙科诊所管理系统的设计与实现~ 开发语言:Java数据库:MySQL技术:SpringSpringMVCMyBatis工具:IDEA/Ecilpse、Navicat、Maven 系统展示 前台主页 后台界面 摘要 随着社会的不断发展和人们生活水平的提高,牙…