这节讲一下多线程(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# 多线程技术的更多相关文章

  1. iOS多线程技术方案

    iOS多线程技术方案 目录 一.多线程简介 1.多线程的由来 2.耗时操作的模拟试验 3.进程和线程 4.多线程的概念及原理 5.多线程的优缺点和一个Tip 6.主线程 7.技术方案 二.Pthrea ...

  2. C#多线程技术总结(异步)

    我这里针对现有的C#多线程技术进行一个汇总,一是复习,二是方便索引,文章部份知识点来源于网络,非本人原创. 一.并行(异步): 1.System.Threading.Tasks命名空间下的(TPL): ...

  3. iOS开发之多线程技术

    本篇争取一篇讲清讲透,依然将通过四大方面清晰的对iOS开发中多线程的用法进行详尽的讲解: 一.什么是多线程 1)多线程执行原理 2)线程与进程 3)多线程的优缺点 二.我们为什么要用多线程编程技术 三 ...

  4. iOS多线程技术

    iOS多线程技术主要分配NSThread.NSOperation和GCD.下边来简单的介绍一下吧. 随性一点,就不按照顺序来了.所以先介绍一下NSOperation. ---------------- ...

  5. 多线程技术 NSThread & NSOperation & GCD

    多线程:在iOS开发中,用到多线程的处理问题的时候有很多,比如异步下载数据时刷新界面等等. 引入多线程来处理问题的关键就是,基于多线程可以使界面更加流畅,防止界面假死. 界面假死:比如你单击一个按钮来 ...

  6. iOS的三种多线程技术NSThread/NSOperation/GCD

    1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的"并发"技术,使得程序员可以不再去关心 ...

  7. 多线程技术在iOS开发中的使用

    进程和线程 要使用多线程,首先需要理解进程和线程这2个概念.这里我简单的说一下. 所谓进程对应的是一个应用程序,负责开辟内存空间供应用程序使用,但是进程不能执行任务(指令).一个进程至少包含一条线程, ...

  8. Java多线程技术学习笔记(二)

    目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...

  9. C++多线程技术windows常用方法

    随着计算机CPU计算能力快速提高,计算机的处理性能和并行性能力也大大提升.那么,一味使用运行时标准库的C++语言也应该开始支持多线程技术.今天,我为大家带来了C++在windows平台下的常用多线程方 ...

  10. VC中利用多线程技术实现线程之间的通信

    当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...

随机推荐

  1. 有必要了解的大数据知识(二) Hadoop

    前言 接上文,复习整理大数据相关知识点,这章节从MapReduce开始... MapReduce介绍 MapReduce思想在生活中处处可见.或多或少都曾接触过这种思想.MapReduce的思想核心是 ...

  2. 攻防世界 reverse Windows_Reverse2

    Windows_Reverse2   2019_DDCTF 查壳: 寻找oep-->dump-->iat修复   便可成功脱壳 int __cdecl main(int argc, con ...

  3. PTA 利用指针找最大值

    6-6 利用指针找最大值 (10 分)   本题要求实现一个简单函数,找出两个数中的最大值. 函数接口定义: void findmax( int *px, int *py, int *pmax ); ...

  4. 【LiteOS】LiteOS消息队列-实战

    目录 前言 链接 参考 笔录草稿 创建测试任务 部分源码 前言 链接 LiteOS源码链接 常见问题 华为开发者社区 华为LiteOS官方教程 我的gitee-LiteOS-mcu 参考 上面链接 笔 ...

  5. C语言之文件操作

    C语言之文件操作 在本节我们将会讲解有关文件的读写操作: 纲要: 一些需要掌握的知识点 文件名 文件类型 数据流 文件缓冲区 文件指针 与文件操作相关的一些函数 文件的打开及关闭 文件的顺序读写 文件 ...

  6. Logback简介及配置文件logback.xml详解

    logback简介及配置文件说明 @author:wangyq @date:2021年3月31日 logback简介 ​ Logback是由log4j创始人设计的另一个开源日志组件,官方网站: htt ...

  7. windows2003配置IIS

    这里采用的是vmbox虚拟机 用这个加载光驱, 使其加载Windows2003的安装镜像 挂载后根据下列操作 点击下一步等加载,加载到这个界面即可 在这里选择应用程序服务器(iis.asp.net), ...

  8. HarmonyOS开发者看过来,HDD上海站传递的重要信息都在这里

    4月17日,颇有HarmonyOS年度总结性质的HarmonyOS开发者日活动上海站正式开始. 活动中,华为消费者业务AI与智慧全场景业务部副总裁段孟对HarmonyOS生态建设的最新进展做了发言,并 ...

  9. MySQL8开启ssl加密

    1 概述 MySQL从5.7开始默认开启SSL加密功能,进入MySQL控制台后输入status可以查看ssl的状态,出现下图表示在使用ssl: 另外,ssl加密需要密钥与证书,可以使用openssl手 ...

  10. 安装电脑思考到了Java设计模式:建造者模式

    目录 定义 意图 主要解决问题 何时使用 优缺点 结构 组装电脑的例子 定义 建造者模式是对象的创建型模式,可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表 ...