C#多线程入门概念及技巧
C#多线程入门概念及技巧
- 一、什么是线程
- 1.1线程的概念
- 1.2为什么要多线程
- 1.3线程池
- 1.4线程安全
- 1.4.1同步机制
- 1.4.2原子操作
- 1.5线程安全示例
- 1.5.1示例一
- 1.5.2示例二
- 1.6C#一些自带的方法实现并行
- 1.6.1 Parallel——For、ForEach、Invoke
- 1.6.1 PLINQ——AsParallel、AsSequential、AsOrdered
- 1.7Semaphore
一、什么是线程
1.1线程的概念
- 线程是操作系统中能够独立运行的最小单位,也是程序中能够并发执行的一段指令序列
- 线程是进程的一部分,一个进程可以包括多个线程,这个线程可以共享进程的资源
- 进程有入口线程,也可用创建更多的线程
1.2为什么要多线程
- 批量重复任务希望同时进行
- 多个不同任务希望同时进行,并且互不干扰
1.3线程池
- 一组预先创建的线程,可以被重复使用来执行多个任务
- 避免频繁地创建和销毁线程,从而减少了现成创建和销毁的开销,提高了系统的性能和效率
- 异步编程默认使用线程池
1.4线程安全
多个线程访问共享资源时,对共享资源的访问不会导致数据不一致或不可预期的结果
1.4.1同步机制
- 用于协调和控制多个线程之间的执行顺序和互斥访问共享资源
- 确保线程按照特定的顺序执行,避免竞态条件和数据不一致的问题
1.4.2原子操作
- 在执行过程中不会被中断的操作,不可分割,要么完全执行,要么完全不执行,没有中间状态
- 在多线程环境下,原子操作能够保证数据的一致性和可靠性,避免出现竞太条件和数据竞争的问题
1.5线程安全示例
1.5.1示例一
两个线程对一个变量进行操作,每个线程都让count增加10000,代码如下:
namespace ThreadStudy
{class Thread_Lock{const int total = 100_000; public static int count = 0;static void Main(string[] args){Thread thread1 = new Thread(new ThreadStart(ThreadMethod));Thread thread2 = new Thread(new ThreadStart(ThreadMethod));thread1.Start();thread2.Start();thread1.Join();thread2.Join();Console.WriteLine($"Count:{count}");}public static void ThreadMethod(){for (int i = 0; i < total; i++)count++;}}
}
输出结果确不为两万,并且每次都不一样:
这是因为线程一在访问并修改这个变量值的时候,另一个线程也在访问并修改这个值,这就会导致一个线程修改后的值被另一个线程修改后的值给覆盖,这个时候我们就需要加锁,修改后的代码如下:
class Thread_Lock{const int total = 100_000; public static int count = 0;public static object lockobjcet = new object();static void Main(string[] args){Thread thread1 = new Thread(new ThreadStart(ThreadMethod));Thread thread2 = new Thread(new ThreadStart(ThreadMethod));thread1.Start();thread2.Start();thread1.Join();thread2.Join();Console.WriteLine($"Count:{count}");}public static void ThreadMethod(){for (int i = 0; i < total; i++){lock (lockobjcet)count++;//这么写也可用 原子操作://count++在底层可能经过了很多步才加一 这个过程中数据可能被其它线程更改//原子操作能一步完成,防止其它线程对变量进行更改//Interlocked.Increment(ref count);}}}
输出结果:
1.5.2示例二
正常结果是要输出0-19,不加锁的情况下就会输出一些无序数
public static Queue<int> queue = new Queue<int>();public static object lockObject = new object();static void Main(string[] args){Thread producer = new Thread(new ThreadStart(AddNumber));Thread consumer1 = new Thread(new ThreadStart(WriteNumber));Thread consumer2 = new Thread(new ThreadStart(WriteNumber));producer.Start();consumer1.Start();consumer2.Start();producer.Join();consumer1.Interrupt();consumer2.Interrupt();consumer1.Join();consumer2.Join();}public static void AddNumber(){for (int i = 0; i < 20; i++){Thread.Sleep(20);queue.Enqueue(i);}}public static void WriteNumber(){try{while (true){lock(lockObject)if (queue.TryDequeue(out var res)){Console.WriteLine(res);Thread.Sleep(1);}}}catch (Exception){Console.WriteLine("Thread interrupted");}}
输出结果:
1.6C#一些自带的方法实现并行
1.6.1 Parallel——For、ForEach、Invoke
正常For循环需要4s
class Program{static void Main(string[] args){var sw = Stopwatch.StartNew();for (int i = 0; i < 20; i++){Thread.Sleep(200);Console.WriteLine($"I:{i}");}Console.WriteLine($"Elapsed time: {sw.ElapsedMilliseconds}ms");}}
使用Parallel进行For循环:
效果提升近10倍,美滋滋
class Program{static void Main(string[] args){var sw = Stopwatch.StartNew();for (int i = 0; i < 20; i++){Thread.Sleep(200);Console.WriteLine($"I:{i}");}Console.WriteLine($"Elapsed time: {sw.ElapsedMilliseconds}ms");}}
1.6.1 PLINQ——AsParallel、AsSequential、AsOrdered
//ToDo 后续补充
1.7Semaphore
Semaphore可以控制线程开启的多少,比如Parallel.For开启了5个线程,而Semaphore定义只能开启三个,当有三个线程正在做时,那么其它的线程就不能够再做,Semaphore等待后要释放掉,最后面还需要Dispose,之前用Parallel在不控制线程的情况下需要400ms,现在控制线程数量,需要1400ms
static void Main(string[] args){var sw = Stopwatch.StartNew();//第一个参数 最开始有几个线程可以用 第二个参数 最多可以同时用几个线程var seamphore = new Semaphore(3, 3);Parallel.For(0, 20, i =>{seamphore.WaitOne();Thread.Sleep(200);Console.WriteLine($"I:{i}");seamphore.Release();});seamphore.Dispose();Console.WriteLine($"Elapsed time: {sw.ElapsedMilliseconds}ms");}
相关文章:

C#多线程入门概念及技巧
C#多线程入门概念及技巧 一、什么是线程1.1线程的概念1.2为什么要多线程1.3线程池1.4线程安全1.4.1同步机制1.4.2原子操作 1.5线程安全示例1.5.1示例一1.5.2示例二 1.6C#一些自带的方法实现并行1.6.1 Parallel——For、ForEach、Invoke1.6.1 PLINQ——AsParallel、AsSequential…...

c primer plus_chapter_four——字符串和格式化输入/输出
1、strlen();const;字符串;用c预处理指令#define和ANSIC的const修饰符创建符号常量; 2、c语言没有专门储存字符串的变量类型,字符串被储存在char类型的数组中;\0标记字符串的结束&a…...
Python Fastapi+Vue+JWT实现注册、登录、状态续签【登录保持】
文章目录 一、实现流程1.注册2.登录3.登录保持【状态续签】二、实现方法1.注册2.登录+登陆状态保持* 后端部分* 前端部分一、实现流程 1.注册 Created with Raphal 2.3.0...

oracle-sql语句解析类型
语句执行过程:1. 解析(将sql解析成执行计划) 2.执行 3.获取数据(fetch) 1. shared pool的组成。 share pool是一块内存池。 主要分成3块空间。free, library(库缓存,缓存sql以及执行计划),row cache(字典缓存) select * from v…...

2023 年最新企业微信官方会话机器人开发详细教程(更新中)
目标是开发一个简易机器人,能接收消息并作出回复。 获取企业 ID 企业信息页面链接地址:https://work.weixin.qq.com/wework_admin/frame#profile 自建企业微信机器人 配置机器人应用详情 功能配置 接收消息服务器配置 配置消息服务器配置 配置环境变量…...
3、FFmpeg基础
1、FFmpeg 介绍 FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库。 2、FFmpeg 组成 - libavformat:用于各种音视频[封装…...

c语言:用指针解决有关字符串等问题
题目1:将一个字符串str的内容颠倒过来,并输出。 数据范围:1≤len(str)≤10000 代码和思路: #include <stdio.h> #include<string.h> int main() {char str1[10000];gets(str1);//读取字符串内容char* p&str1[…...

吃透 Spring 系列—Web部分
目录 ◆ Spring整合web环境 - Javaweb三大组件及环境特点 - Spring整合web环境的思路及实现 - Spring的web开发组件spring-web ◆ web层MVC框架思想与设计思路 ◆ Spring整合web环境 - Javaweb三大组件及环境特点 在Java语言范畴内,web层框架都是基于J…...
JAVA后端服务端与移动端客户端高精度时间同步思路
一、脑补 在Chrome--->Network----> Timing中可以查看一个请求在各个阶段所花费的时间。 Timing中各个字段的意思发: 1、Queueing:从增加到等待处理队列到实际开始处理的时间间隔——浏览器也有线程机制,所有的请求不能同时发送&…...
nsd的资料
nsd是一款开源的DNS服务器应用。 近期参与项目过程中,涉及到DNS业务,结果被打的满头包。 虽然在校学习时就知道DNS协议,但从业这么多年,对于DNS协议的理解其实一直处于一知半解的状态。 当前处理问题时,接触到了nsd&am…...

关于Maven中pom.xml文件不报错但无法导包解决方法
问题 我的pom文件没有报红,但是依赖无法正常导入。 右下角还总出现这种问题。 点开查看报错日志。大致如下 1) Error injecting constructor, java.lang.NoSuchMethodError: org.apache.maven.model.validation.DefaultModelValidator: method <init>()V no…...
使用决策树分类
任务描述 本关任务:使用决策树进行分类 相关知识 为了完成本关任务,你需要掌握:1.使用决策树进行分类 使用决策树进行分类 依靠训练数据构造了决策树之后,我们可以将它用于实际数据的分类。在执行数据分类时,需要…...

STM32H563烧录后无法擦除
STM32H563烧录后无法擦除,使用STM32CubeProgrammer连接后显示如下图所示。...

2023最新最全【Adobe After Effection 2023】下载安装零基础教程【附安装包】
AE2023下载点这里 教学 1.鼠标右击【Ae2023(64bit)】压缩包选择(win11系统需先点击“显示更多选项”)【解压到 Ae2023(64bit)】。 2.打开解压后的文件夹,鼠标右击【Set-up】选择【以管理员身份运行】。 3.点击【文件夹图标】,…...

【Spring之底层核心架构概念解析】
文章目录 一、BeanDefinition二、BeanDefinitionReader2.1、AnnotatedBeanDefinitionReader2.2、XmlBeanDefinitionReader 五、ClassPathBeanDefinitionScanner六、BeanFactory七、ApplicationContext7.1、AnnotationConfigApplicationContext7.2、ClassPathXmlApplicationCont…...

手把手带你创建一个自己的GPTs
大家好,我是五竹。 最近GPT又进行了大升级,这一下又甩了国内AI几条街,具体更新了哪些内容之前的一篇文章中其实已经说过了:ChatGPT 王炸升级!更强版 GPT-4 上线! 其中最重要的一点就是支持自定义GPT&…...
Vue 组件+es6箭头函数+路由
一、组件 1、让网页或局部页实现复用,包括js(vue)功能 组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素, …...

Clickhouse学习笔记(5)—— ClickHouse 副本
Data Replication | ClickHouse Docs 副本的目的主要是保障数据的高可用性,即使一台 ClickHouse 节点宕机,那么也可以从其他服务器获得相同的数据 注意: clickhouse副本机制的实现要基于zookeeperclickhouse的副本机制只适用于MergeTree f…...
ELMo模型、word2vec、独热编码(one-hot编码)的优缺点进行对比
下面是对ELMo模型、word2vec和独热编码(one-hot编码)的优缺点进行对比: 独热编码(One-hot Encoding): 优点: 简单,易于理解。适用于词汇表较小的场景。 缺点: 高维度…...

FFmpeg简介1
适逢FFmpeg6.1发布,准备深入学习下FFmpeg,将会写下系列学习记录。 在此列出主要学习资料,后续再不列,感谢这些大神的探路和分享,特别是雷神,致敬! 《FFmpeg从入门到精通》 《深入理解FFmpeg》 …...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
文章目录 一、开启慢查询日志,定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...

【51单片机】4. 模块化编程与LCD1602Debug
1. 什么是模块化编程 传统编程会将所有函数放在main.c中,如果使用的模块多,一个文件内会有很多代码,不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数声明,其他.c文…...