C# 多线程技术
这节讲一下多线程(Thread)技术。
在讲线程之前,先区分一下程序,进程,线程三者的区别,大体上说,一个程序可以分为多个进程,一个进程至少由一个线程去执行,它们是层层包含的关系。我们写的程序,就是一个进程,多个进程,以完成一个用户服务,或者完成一个大的界面展现,就组成一个程序,但在CPU层面,只有线程的概念,线程是最小的执行单位,Windows中采用CPU轮换制度,CPU给每个要执行的线程分配操作时间,轮流执行,但因为CPU的主频实在是太高,我们感受不到每个程序轮空期卡顿。
一个进程,开了一条线程去执行,那么这个线程就是主线程,一般在UI程序中,如果主线程执行CPU密集型的耗时工作(如IO操作),那么就会导致界面处于”假死“状态,直到主线程完成这个耗时的任务,所以,我们需要解决这种假死的问题,以带给用户更好的交互体验,那么就要用到多线程技术,将耗时的工作,交给后台线程执行。
创建线程
使用Thread类创建线程,该类位于System.Thread类之下,必须在创建之时给填入执行方法,或者填入lambda表达式。
Thread thread=new Thread(() =>
{
for (int i = 0; i <= 100; i++)
{
Console.WriteLine($"{Thread.CurrentThread.Name}=========>{i}");
}
});
以上是创建了一个线程,并填入一个lambda表达式,输出当前线程的名称和0-100,注意,创建并不是启动,启动需要调用Start()方法。
下面看一段完整的代码:
Thread thread=new Thread(() =>
{
Console.WriteLine(Thread.CurrentThread.IsAlive);
for (int i = 0; i <= 100; i++)
{
Console.WriteLine($"{Thread.CurrentThread.Name}=========>{i}");
}
});
thread.Name = "BackgroundThread";
thread.IsBackground = true;
thread.Start();
for (int i = 0; i <= 100; i++)
{
Console.WriteLine($"main=========>{i}");
}
Console.WriteLine(thread.ManagedThreadId);
Thread.Sleep(200);
Console.WriteLine(thread.IsAlive);
先介绍一下代码中出现的几个属性和方法:
Name属性,故名思意,这是为线程起一个名字,
IsBackground属性,设置线程是否是后台线程,如果前台线程也就是主线程结束运行,它所有的后台线程也会立即终止。
IsAlive只读bool属性,标识当前线程是否执行完毕,这里要说一下线程的生命周期,它的声明周期是从开始执行到结束,执行完交给线程的代码线程立即dead掉,也可以强行挂起线程,但这个方法已被舍弃,因为强行挂起线程有弊端,就像在高速上跑的小汽车,不能随便就直接拦截。
ManagedThreadId属性,获取当前线程ID
Thread.CurrentThread属性,获取当前的线程。
Thread.Sleep(毫秒值)方法,执行到此方法,线程会睡眠,哪个线程执行,哪个线程睡,此处让其睡200毫秒,为了展示IsAlive属性。
Start()方法,是让这个线程启动。
接下来看一下运行结果(为了方便查看结果,我把循环都调成了6次):
可以看到,执行中的IsAlive属性是true,睡了200秒,线程执行完毕,IsAlive属性变为flase。
Join方法
线程调用join()方法,是指示CPU该线程交出自己的执行权(也就是该线程处于阻塞状态),直到其它线程执行执行完毕,Join()方法有个毫秒值重载,用于设置交出执行权多少时间。将上方代码更改后:
Thread thread=new Thread(() =>
{
for (int i = 0; i <= 20; i++)
{
Console.WriteLine($"{Thread.CurrentThread.Name}=========>{i}");
if (i == 10)
{
Thread.CurrentThread.Join(200);
}
}
});
thread.Name = "BackgroundThread";
thread.IsBackground = true;
thread.Start(); for (int i = 0; i <= 20; i++)
{
Console.WriteLine($"main=========>{i}");
}
Thread.Sleep(200);
执行结果为:
当在i=10的时候,后台线程交出了执行权200毫秒,这期间只有主线程在工作。
线程的优先级
线程的优先级是可以设置的,但是,这仅仅是人为了提高了线程的优先级,至于真正的调配还得看CPU,所以一般多线程开发,是很繁琐的事情,维护起来也困难,所以多线程技术需要慎用,不能滥用。
线程优先级有个枚举类,源码如下:
public enum ThreadPriority
{
Lowest,//优先级最低
BelowNormal,//低于正常
Normal,//正常
AboveNormal,//较高
Highest,//最高
}
当我将其优先级更改为最高时,也并不能决定它是最快执行的,所以优先级的设置只是理论上的。
线程池
线程池是系统事先创建好的一堆后台线程,当一个程序需要一个后台线程执行一个不太重要的线程,并且代码简短的话,可以使用线程池,不用再自己new一个线程,这能略微提高性能。
ThreadPool.QueueUserWorkItem(s => Console.WriteLine(s),"helloworld");
使用 ThreadPool.QueueUserWorkItem()创建一个线程池线程,当线程池中有空闲线程时会取出一个线程来执行。须注意的是,第一个参数是一个带有一个参数的委托WaitCallback,第二个参数会作为这个委托的参数传入。
public delegate void WaitCallback(object state);
线程安全
不得不提的是,多线程存在线程安全问题,所以在开发时要注意。何为线程安全呢,举个例子,火车站售票,1000个人同时抢100张票,多线程情况下,有可能两个甚至多个线程同时抢到一个票,最后这几个线程都是一个座号,这显然是不合情理的。解决线程安全问题,就必须保证共享数据的同步性,也就是说同一时间只有一个线程访问共享的数据,关于线程安全的例子,我会在下一期进行讲解。
这是我的公众号二维码,获取最新文章,请关注此号
C# 多线程技术的更多相关文章
- iOS多线程技术方案
iOS多线程技术方案 目录 一.多线程简介 1.多线程的由来 2.耗时操作的模拟试验 3.进程和线程 4.多线程的概念及原理 5.多线程的优缺点和一个Tip 6.主线程 7.技术方案 二.Pthrea ...
- C#多线程技术总结(异步)
我这里针对现有的C#多线程技术进行一个汇总,一是复习,二是方便索引,文章部份知识点来源于网络,非本人原创. 一.并行(异步): 1.System.Threading.Tasks命名空间下的(TPL): ...
- iOS开发之多线程技术
本篇争取一篇讲清讲透,依然将通过四大方面清晰的对iOS开发中多线程的用法进行详尽的讲解: 一.什么是多线程 1)多线程执行原理 2)线程与进程 3)多线程的优缺点 二.我们为什么要用多线程编程技术 三 ...
- iOS多线程技术
iOS多线程技术主要分配NSThread.NSOperation和GCD.下边来简单的介绍一下吧. 随性一点,就不按照顺序来了.所以先介绍一下NSOperation. ---------------- ...
- 多线程技术 NSThread & NSOperation & GCD
多线程:在iOS开发中,用到多线程的处理问题的时候有很多,比如异步下载数据时刷新界面等等. 引入多线程来处理问题的关键就是,基于多线程可以使界面更加流畅,防止界面假死. 界面假死:比如你单击一个按钮来 ...
- iOS的三种多线程技术NSThread/NSOperation/GCD
1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的"并发"技术,使得程序员可以不再去关心 ...
- 多线程技术在iOS开发中的使用
进程和线程 要使用多线程,首先需要理解进程和线程这2个概念.这里我简单的说一下. 所谓进程对应的是一个应用程序,负责开辟内存空间供应用程序使用,但是进程不能执行任务(指令).一个进程至少包含一条线程, ...
- Java多线程技术学习笔记(二)
目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...
- C++多线程技术windows常用方法
随着计算机CPU计算能力快速提高,计算机的处理性能和并行性能力也大大提升.那么,一味使用运行时标准库的C++语言也应该开始支持多线程技术.今天,我为大家带来了C++在windows平台下的常用多线程方 ...
- VC中利用多线程技术实现线程之间的通信
当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...
随机推荐
- Django分页器组建
class Pagination(object): def __init__(self,current_page,all_count,per_page_num=2,pager_count=11): & ...
- Python深入:setuptools进阶
作者:gqtcgq 来源:CSDN 原文:https://blog.csdn.net/gqtcgq/article/details/49519685 Setuptools是Python Distuti ...
- 9、Spring教程之AOP
那我们接下来就来聊聊AOP吧! 1.什么是AOP AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.A ...
- 在ASP.NET Core中用HttpClient(四)——提高性能和优化内存
到目前为止,我们一直在使用字符串创建请求体,并读取响应的内容.但是我们可以通过使用流提高性能和优化内存.因此,在本文中,我们将学习如何在请求和响应中使用HttpClient流. 什么是流 流是以文件. ...
- Python转义字符中'\'的个数问题
Python转义字符中''的个数问题 如果字符串里面有很多字符都需要转义,就需要加很多\,为了简化,Python还允许用r' '或者r" "表示''或" "内部 ...
- kubernetes 降本增效标准指南| 资源利用率提升工具大全
背景 公有云的发展为业务的稳定性.可拓展性.便利性带来了极大帮助.这种用租代替买.并且提供完善的技术支持和保障的服务,理应为业务带来降本增效的效果.但实际上业务上云并不意味着成本一定较少,还需适配云上 ...
- M3D - 一个想突破又还有很多包袱的新生三维数据格式杂谈
目录 1 门派 2 几个术语简析 3 结构简析 3.1 空间剖分方式 3.2 空间范围表示方式 4 M3DDataInfo.mcj 类定义 5 NodeInfo.json 类定义 6 *.m3d 文件 ...
- 附031.Kubernetes_v1.20.4高可用部署架构二
kubeadm介绍 kubeadm概述 参考附003.Kubeadm部署Kubernetes. kubeadm功能 参考附003.Kubeadm部署Kubernetes. 本方案描述 本方案采用kub ...
- Spring Cloud微服务限流之Sentinel+Apollo生产实践
Sentinel概述 在基于Spring Cloud构建的微服务体系中,服务之间的调用链路会随着系统的演进变得越来越长,这无疑会增加了整个系统的不可靠因素.在并发流量比较高的情况下,由于网络调用之间存 ...
- 6.3string用法
string类型可以大大方便对字符串的处理 1.string的定义 string str; string str="abcd"; 2.string中内容的访问 (1)可以像字符数组 ...