《learning hard C#学习笔记》读书笔记(19)多线程
19.1 多线程编程知识
19.1.1 进程与线程的概念
可以理解为一块包含某些资源的内存区域,操作系统通过进程方式把它工作划分为不同的单元。
一个应用程序可以对应多个进程。
线程是进程中的独立执行单元,操作系统调度线程来使应用程序工作。
一个进程中至少包含一个线程,称为主线程。
19.1.2 线程的调度
1、Time-critical:关键时间(最高的相对线程优先级)
2、Heightest:最高(翻译是这么翻译,但是并不是最高的相对线程优先级)
3、Above normal:高于标准
4、Normal:标准
5、Below normal:低于标准
6、Lowest:最低(翻译是这么翻译,但是并不是最低的相对线程优先级)
7、Idle:空闲
19.1.3 线程也分前后台
|
CLRT + F5 (不调试)效果图

通过分析,按 CLRT + F5 运行程序,你将会看到如图效果。如果按 F5 你将会看到输出结果一闪而过,因为主线程退出后,整个应用程序也跟着退出,就关闭了控制台程序。
1.所创建线程默认为非后台线程,所以注释掉 //backThread.IsBackground = true;(这时候不是后台线程了)

2.使主线程在后台线程执行完毕后再执行,即使主线程进入睡眠,且睡眠时间比后台线程长。




public Thread(ParameterizedThreadStart start, int maxStackSize);
19.2 线程的容器——线程池
19.2.1 线程池
线程池是一个存放线程的地方,这种集中存放有利于线程的管理。
CLR初始化时,线程池中没有线程。(线程池内部维护了一个操作请求队列).
执行异步操作时,需要调用 QueueUserWorkItem 方法将任务添加到线程池队列。线程池实现的代码会从队列中提取任务,并委派给线程池中的线程执行。
没有空闲的线程,线程池会创建一个新线程去执行提取的任务。
当线程池完成了某个任务,线程不会销毁,而是返回到线程池中,等待下一个请求。(由于不销毁,所以不会产生性能损失)
线程池创建的是后台线程,优先级是 Normal 。
19.2.2 通过线程池来实现多线程
使用线程池的线程,要调用静态方法 ThreadPool.QueueUserWorkItem ,以指定线程要调用的方法。该静态方法有两种:
public static bool QueueUserWorkItem(WaitCallback callBack);
public static bool QueueUserWorkItem(WaitCallback callBack, object state);
这两个方法用于向线程池队列添加一个工作项(work item)以及一个可选的状态数据。
工作项是指一个由 callback 参数标识的委托对象,被委托对象包装的回调方法由线程池来执行。
传入的回调方法匹配 System.Threading.WaitCallback 委托类型
|

19.2.3 协作式取消线程池线程
.NET Framework 提供了取消操作的模式,这个模式是协作式的。为了取消操作,我们必须创建一个 System.Threading.CancellationTokenSource 对象。
|
首先创建一个 CancellationTokenSource 实例,将该实例作为参数传入QueueUserWorkItem 方法。线程池会创建一个线程池线程,运行该方法传入的回调函数 callback ,并在 callback 中执行 Count 函数来计数。
在 Count 函数中检查 CancellationTokenSource 类实例的状态。当用户按回车键时,该实例的 IsCancellationRequested 属性将返回 ture 。因此退出 Count 方法。否则一直运行。

19.3 线程同步
多线程中,为了保证后者线程,只有等待前者线程完成之后才能继续执行。好比排队买票,前面的人没买票之前,后面的人必须等待。
19.3.1 多线程程序中存在的隐患
多线程可以提高程序的性能和用户体验。然而当我们创建多个线程后,它们可能同时访问某一个共享资源,这将损坏资源中所保存的数据。这时候我们需要使用线程同步,确保某一时刻只有一个线程在操作共享资源。
举例来说,火车票销售系统允许多人同时购买,因此该系统肯定采用了多线程技术。但由于系统中有多个线程在对同一资源(火车票)进行操作,我们必须确保只有其他线程执行结束后,新的线程才开始执行。这样可以避免多位顾客买到同一张票。
|
线程1从100张票开始出售,执行一段时间后,线程2开始执行,执行一段时间后,线程1又继续执行,两个线程交替,直至售完100张票。

19.3.2 使用监视器对象实现线程同步
监视器对象(Monitor)能够确保线程拥有对共享资源的互斥访问权,C# 通过 lock 关键字来提供简化语法。
|
使用 Monitor 锁定的对象需要引用类型,而不是值类型。
因为值类型变量传递给方法时,它将被装箱为一个单独的对象,之后传递给 Enter 方法;
而在将变量传递给 Exit 方法时,也会创建一个单独的引用对象。此时,传递给 Enter 方法的对象和传递给 Exit 方法的对象不同, Monitor 将会引发 SynchronizationLockException 异常。

使用 try.....finally 语句执行 Monitor ,如果不使用,程序会出现“死锁现象”;
19.3.3 线程同步技术存在的问题
它的使用比较繁琐。要用额外的代码把被多个线程同时访问的数据保卫起来,并获取和释放线程的同步锁。如果一个代码块忘记获取锁,就可能造成数据损坏。
使用线程同步会影响程序性能。因为获取和释放同步锁需要时间,并且决定哪个线程先获取锁,CPU也必须进行协调。
线程同步每次只允许一个线程访问资源,会导致线程阻塞。继而,系统会创建更多的线程,CPU也就负担更繁琐的调度工作。
|
调用 StartNew 函数对 Stopwatch 实例化,将运行时间设为0,开始测量时间。

《learning hard C#学习笔记》读书笔记(19)多线程的更多相关文章
- 《Hands-On Machine Learning with Scikit-Learn&TensorFlow》读书笔记
一 机器学习概览 机器学习的广义概念是:机器学习是让计算机具有学习的能力,无需进行明确编程. 机器学习的工程性概念是:计算机程序利用经验E学习任务T,性能是P,如果针对任务T的性能P随着经验E不断增长 ...
- 鸟哥Linux私房菜 基础学习篇读书笔记(10):Linux磁盘和文件系统管理(3)
本文总结了Linux操作系统来管理我们的硬盘和文件系统需要使用命令.当我们在系统中增加一个硬盘驱动器.什么是我们需要去通过这个硬盘就可以真正使用步骤?下面步骤: (1)对磁盘进行分区,新建能够使用的分 ...
- 鸟哥的Linux私房菜 基础学习篇读书笔记(9):Linux磁盘与文件系统管理(2)
上一篇文章主要从理论上分析了Linux的Ext2文件系统.这一篇主要解说怎样查看Linux的文件系统的容量以及解说Linux文件系统中的连接文件. 能够通过df和du命令来查看磁盘与文件夹的容量.df ...
- 人体和电脑的关系——鸟哥的LINUX私房菜基础学习篇读书笔记
CUP=脑袋: 每个人会做的事情都不一样(指令集的差异),但主要都是通过脑袋来判断与控制身体各部分的行动 内存=脑袋中存放正在思考的数据区块: 在实际活动过程中,我们的脑袋需要有外界刺激的数据(例如光 ...
- 人生效率手册:如何卓有成效地过好每一天--By张萌姐姐--读书笔记
读书笔记:<人生效率手册>:如何卓有成效地过好每一天--By张萌姐姐... 整本书看完的感受: 这本书主要讲的是生活中我们需要给自己一个目标,然后通过自己的努力去实现这个目标,书中说的很多 ...
- 强化学习读书笔记 - 06~07 - 时序差分学习(Temporal-Difference Learning)
强化学习读书笔记 - 06~07 - 时序差分学习(Temporal-Difference Learning) 学习笔记: Reinforcement Learning: An Introductio ...
- 【Deep Learning读书笔记】深度学习中的概率论
本文首发自公众号:RAIS,期待你的关注. 前言 本系列文章为 <Deep Learning> 读书笔记,可以参看原书一起阅读,效果更佳. 概率论 机器学习中,往往需要大量处理不确定量,或 ...
- Deep Learning(深度学习)学习笔记整理系列之(八)
Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...
- 强化学习读书笔记 - 02 - 多臂老O虎O机问题
# 强化学习读书笔记 - 02 - 多臂老O虎O机问题 学习笔记: [Reinforcement Learning: An Introduction, Richard S. Sutton and An ...
- 强化学习读书笔记 - 05 - 蒙特卡洛方法(Monte Carlo Methods)
强化学习读书笔记 - 05 - 蒙特卡洛方法(Monte Carlo Methods) 学习笔记: Reinforcement Learning: An Introduction, Richard S ...
随机推荐
- 浅谈:javascript的面向对象编程之具体实现
下面的javascript代码都是需要使用jQuery插件来做的.希望大家可以搭建好工作环境 首先我们来做一个练习:在一个删除的超链接中添加一个提示信息,提示是否确认删除. 一般情况下我们都会这么做 ...
- pdo in 查询
$ids1 = implode(",",$upload_ids);if(!empty($upload_ids)){ $ids_db= pdo_fetchall('select id ...
- 接口测试 postman
1.可以应用一些简单的测试点 2. api有多个域名,放进collection里面进行批量测试,点击左上角'runner'
- 继承 原生js 与 $.extend(true,default,opts||{});
$.extend(true,default,opts||{}); var obj1={ name:'liu', sex:'m', work:'pc' } var obj2={ sex:'w' } va ...
- c# .Net :Excel NPOI导入导出操作教程之数据库表信息数据导出到一个Excel文件并写到磁盘示例分享
string sql = @"select * from T_Excel"; ----------------DataTable Star---------------- ...
- Nodejs事件引擎libuv源码剖析之:高效队列(queue)的实现
声明:本文为原创博文,转载请注明出处. 在libuv中,有一个只使用简单的宏封装成的高效队列(queue),现在我们就来看一下它是怎么实现的. 首先,看一下queue中最基本的几个宏: typede ...
- Spring MVC学习笔记——SiteMesh的使用(转)
转自 SiteMesh的使用 SiteMesh的介绍就不多说了,主要是用来统一页面风格,减少重复编码的. 它定义了一个过滤器,然后把页面都加上统一的头部和底部. 需要先在WEB-INF/lib下引入s ...
- SpringMVC学习记录2
废话 最近在看SpringMVC...里面东西好多...反正东看一点西看一点吧... 分享一下最近的一些心得..是关于DispatcherServlet的 DispatcherServlet与Cont ...
- URL-Short
Fortify URL http://www.hpenterprisesecurity.com/vulncat/en/vulncat/index.html 1.Arstechnica http://a ...
- 使用ASP.NET Web API Help Pages 创建在线接口文档
操作步骤 1.新建Web API项目 2.在项目Areas文件夹下找到以下文件,取消注释图中代码. 3.右键解决方案,属性,如图设置. 4.运行程序,点击右上角API 接口列表: 详情-无参数: 详情 ...