这节讲一下多线程(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. Nuxt.js vue服务端渲染

    一.为什么要用Nuxt.js 原因其实不用多说,就是利用Nuxt.js的服务端渲染能力来解决Vue项目的SEO问题. 二.Nuxt.js和纯Vue项目的简单对比 1. build后目标产物不同 vue ...

  2. Webpack 5 配置手册(从0开始)

    针对新手入门搭建项目,Webpack5 配置手册(从0开始) webpack安装顺序 1. `npm init -y`,初始化包管理文件 package.json 2. 新建src源代码目录 3. 新 ...

  3. 加快Python运行速度

    01 使用哈希表的数据结构 如果在程序中遇到大量搜索操作时,并且数据中没有重复项,则可以使用查找而不是循环.举例如下: items = ['a', 'b',..,'100m'] #1000s of i ...

  4. [BFS]最优乘车

    最优乘车 题目描述 HH 城是一个旅游胜地,每年都有成千上万的人前来观光.为方便游客,巴士公司在各个旅游景点及宾馆,饭店等地都设置了巴士站并开通了一些单程巴上线路.每条单程巴士线路从某个巴士站出发,依 ...

  5. 201871030107-常雅伦 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容 课程班级博客链接 班级博客 这个作业要求链接 作业要求 我的课程学习目标 1.体验软件项目开发中的两人合作,练习结对编程(Pair programming).2.掌握Github协作开发程 ...

  6. Dynamics CRM报表无法访问提示“报表服务器无法访问或使用加密密钥。你可能需要将服务器添加到扩展组,或重新导入”

    当我们部署Dynamics CRM的环境的时候如果报表配置的不规范会出现很多问题,尤其是这个问题相对来说更棘手,解决起来非常麻烦. 网上很多教程都说直接到报表配置页删除密钥就可以了,实际上删除的时候会 ...

  7. ternux的ssh和ftp

    ssh的连接 pkg install ssh ssh -p 8022 username@hostname_ip ftp的创建 安装python 升级pip python -m pip install ...

  8. mp4视频中插入文字

    最近接到一个需求,需要往mp4中动态插入文字,并且mp4中的乌云能在文字上有飘动的效果,一开始想用canvas,但是由于本人经验不足,没什么思路,看到css3有一个属性:mix-blend-mode, ...

  9. tensorflow学习--数据加载

    文章主要来自Tensorflow官方文档,同时加入了自己的理解以及部分代码 数据读取 TensorFlow程序读取数据一共有3种方法: 供给数据(Feeding): 在TensorFlow程序运行的每 ...

  10. 《剑指offer》刷题笔记

    简介 此笔记为我在 leetcode 上的<剑指offer>专题刷题时的笔记整理. 在刷题时我尝试了 leetcode 上热门题解中的多种方法,这些不同方法的实现都列在了笔记中. leet ...