C#当中的多线程_线程基础

时间:2022-12-27 09:44:13

前言

最近工作不是很忙,想把买了很久了的《C#多线程编程实战》看完,所以索性把每一章的重点记录一下,方便以后回忆。

第1章 线程基础

1.创建一个线程

using System;

using System.Threading;

namespace Chapter1.Recipe1
{
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(PrintNumbers); t.Start(); PrintNumbers();
} static void PrintNumbers()
{
Console.WriteLine("Starting..."); for (int i = ; i < ; i++)
{
Console.WriteLine(i);
}
}
}
}

2.改变线程状态的方法

①线程暂停-Sleep()方法

它是Thread类中的一个静态方法,使用方式是Thread.Sleep(timeout);

②线程等待-Join()方法

它是线程实例的一个实例方法,使用时t.Join();(t是线程的一个实例)

说明:该方法允许我们等待直到线程t完成,当t执行完成后,主线程会继续执行。借助这个方法可以简单实现两个线程之间的同步执行顺序。第一个线程会等第二个线程执行完成后再继续执行。此时第一个线程处于阻塞状态。

③终止线程-Abort()方法

它也是一个实例方法,使用方法是t.Abort()。

说明:它终止线程的方法是给线程注入一个ThreadAbortException,导致线程被终结。这个异常可能会导致程序的彻底崩溃。并且这个异常并不一定会终止线程,目标线程可以通过处理该异常并调用Thread.ResetAbort方法来拒绝终止线程。终止线程的方法最好是通过添加一个标志来进行线程的终止。

④检查线程的状态-ThreadState

ThreadState是一个枚举类型,包含了线程运行的几种状态。

⑤线程的优先级

ThreadPriority也是一个枚举类型

 public enum ThreadPriority
{
Lowest = ,
BelowNormal = ,
Normal = ,
AboveNormal = ,
Highest = ,
}

使用方法:

threadOne.Priority = ThreadPriority.Highest;

⑥前台线程和后台线程

IsBackground属性用来区别前台线程和后台线程,默认情况下创建的线程都是前台线程,当把线程的属性IsBackground设置为true的时候,那么则创建一个后台线程。

前台线程和后台线程的区别:进程会等待所有的前台线程执行完之后再去结束,如果只剩下了后台线程则进程会直接结束。

⑦向线程传递参数

方式一:

定义一个类,在类的构造函数当中进行参数的赋值

  class ThreadSample
{
private readonly int _iterations; public ThreadSample(int iterations)
{
iterations = iterations;
}
public void CountNumbers()
{
for (int i = ; i <= _iterations; i++)
{
Thread.Sleep(TimeSpan.FromSeconds(0.5));
Console.WriteLine("{0} prints {1}", Thread.CurrentThread.Name, i);
}
}

调用:

       var sample = new ThreadSample();

       var threadOne = new Thread(sample.CountNumbers);

       threadOne.Name = "ThreadOne";

       threadOne.Start();

       threadOne.Join();

方式二:采用ParameterizedThreadStart的方式

ParameterizedThreadStart是一个委托类型,接收一个object类型的参数。

public delegate void ParameterizedThreadStart(object obj);

使用方法:

Count函数有一个object类型的参数

         static void Count(object iterations)
{
CountNumbers((int)iterations);
} static void CountNumbers(int iterations)
{
for (int i = ; i <= iterations; i++)
{
Thread.Sleep(TimeSpan.FromSeconds(0.5));
Console.WriteLine("{0} prints {1}", Thread.CurrentThread.Name, i);
}
}

调用:

  ParameterizedThreadStart paramThread = new ParameterizedThreadStart(Count);
Thread threadMy = new Thread(paramThread);
threadMy.Name = "My";
threadMy.Start();
threadMy.Join(); 

方式三:采用lambda表达式

 var threadThree = new Thread(() => CountNumbers());
threadThree.Name = "ThreadThree";
threadThree.Start();
threadThree.Join();

() => CountNumbers(12) lambda表达式定义了一个不属于任何类的方法。我们创建了一个方法,该方法使用需要的参数调用了另一个方法,并在另一个线程中运行该方法。

⑧lock关键字

lock关键字来解决线程之间的竞争条件。

在C# lock关键字定义如下: lock(expression) statement_block,其中expression代表你希望跟踪的对象,通常是对象引用。

代码示例如下:

private static object  ojb = new object();

lock(obj)

{

//锁定运行的代码段

}

假设线程A先执行,线程B稍微慢一点。线程A执行到lock语句,判断obj是否已申请了互斥锁,判断依据是逐个与已存在的锁进行object.ReferenceEquals比较(此处未加证实),如果不存在,则申请一个新的互斥锁,这时线程A进入lock里面了。

⑨Monitor类锁定资源

这个类用来避免死锁,之前的lock关键字用来创建死锁,其实lock是Monitor的一个语法糖

首先lock和Minitor有什么区别呢?

Monitor和Lock的区别

1.Lock是Monitor的语法糖。

2.Lock只能针对引用类型加锁。

3.Monitor能够对值类型进行加锁,实质上是Monitor.Enter(object)时对值类型装箱。

4.Monitor还有其他的一些功能。

貼り付け元  <http://www.cnblogs.com/chengxingliang/p/3150731.html>

其实lock在IL代码中会被翻译成Monitor。也就是Monitor.Enter(obj)和Monitor.Exit(obj).

lock(obj)

{

}

等价为:

try

{

Monitor.Enter(obj)

}

catch()

{}

finally

{

Monitor.Exit(obj)

}

所以lock能做的,Monitor肯定能做,Monitor能做的,lock不一定能做。那么Monitor额外的功能呢?

1:Monitor.TryEnter(obj,timespan)----timeout之后,就不执行这段代码了。lock可是一直会死等的。

2:还有Monitor.Wait()和Monitor.Pulse()。在lock代码里面如果调用了Monitor.Wait(),会放弃对资源的所有权,让别的线程lock进来。然后别的线程代码里Pulse一下(让原线程进入到等待队列),然后在Wait一下释放资源,这样原线程的就可以继续执行了(代码还堵塞在wait那句话呢)。

也就是说,必须两个或多个线程共同调用Wait和Pulse,把资源的所有权抛来抛去,才不会死锁。

Monitor的常用属性和方法:

Enter(Object) 在指定对象上获取排他锁。

Exit(Object) 释放指定对象上的排他锁。

IsEntered 确定当前线程是否保留指定对象锁。

Pulse 通知等待队列中的线程锁定对象状态的更改。

PulseAll 通知所有的等待线程对象状态的更改。

TryEnter(Object) 试图获取指定对象的排他锁。

TryEnter(Object, Boolean) 尝试获取指定对象上的排他锁,并自动设置一个值,指示是否得到了该锁。

Wait(Object) 释放对象上的锁并阻止当前线程,直到它重新获取该锁。

C#当中的多线程_线程基础的更多相关文章

  1. C&num;当中的多线程&lowbar;线程池

    3.1 简介 线程池主要用在需要大量短暂的开销大的资源的情形.我们预先分配一些资源在线程池当中,当我们需要使用的时候,直接从池中取出,代替了重新创建,不用时候就送回到池当中. .NET当中的线程池是受 ...

  2. C&num;当中的多线程&lowbar;线程同步

    第2章 线程同步 原来以为线程同步就是lock,monitor等呢,看了第二章真是大开眼界啊! 第一章中我们遇到了一个叫做竞争条件的问题.引起的原因是没有进行正确的线程同步.当一个线程在执行操作时候, ...

  3. C&num;多线程开发-线程基础 01

    最近由于工作的需要,一直在使用C#的多线程进行开发,其中也遇到了很多问题,但也都解决了.后来发觉自己对于线程的知识和运用不是很熟悉,所以将利用几篇文章来系统性的学习汇总下C#中的多线程开发. 线程基础 ...

  4. java核心技术-多线程之线程基础

    说起线程,无法免俗首先要弄清楚的三个概念就是:进程.线程.协程.OK,那什么是进程,什么是线程,哪协程又是啥东西.进程:进程可以简单的理解为运行在操作系统中的程序,程序时静态代码,进程是动态运行着的代 ...

  5. C&num;当中的多线程&lowbar;任务并行库&lpar;中&rpar;

    发现自己有点懒了!也可能是越往后越难了,看书理解起来有点费劲,所以这两天就每天更新一点学习笔记吧. 4.5 将APM模式转化为任务 书上提供的三种方式 方式一: class Program       ...

  6. Java多线程&lpar;一&rpar;——线程基础和锁锁锁

    目录 Java多线程(一) 一.线程的定义 二.Synchronize线程同步 三.偏向锁.自旋锁.重量级锁 四.volatile关键字 五.Compare And Swap无锁自旋优化技术和ABA版 ...

  7. C&num;当中的多线程&lowbar;任务并行库&lpar;下&rpar;

    4.8 处理任务中的异常 下面这个例子讨论了任务当中抛出异常,以及任务异常的获取     class Program     {         static void Main(string[] a ...

  8. C&num;当中的多线程&lowbar;任务并行库&lpar;上&rpar;

    复习: 第三章内容中我们提到了三种异步编程模型,这里简单复习一下,分别如下 1.APM(异步编程模式):形如Beginxxx,Endxxx. 2.EAP(基于事件的异步编程模式):这个我们在.net中 ...

  9. &lbrack;19&sol;04&sol;08-星期一&rsqb; 多线程&lowbar;线程的优先级&lpar;Priority&rpar; 和 守护线程&lpar;Daemon&rpar;

    一.概念 1. 处于就绪状态的线程,会进入“就绪队列”等待JVM来挑选. 2. 线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级是5. 3. 使用下列方法获得或设置线程对象的优先级. in ...

随机推荐

  1. 禁止复制放在js文件中

    1.使右键和复制失效 方法1: 在网页中加入以下代码: 复制代码代码如下: <script language="Javascript"> document.oncont ...

  2. wifi 攻破

    链接1 wifi 加密方式 1,wep加密 2.WPA/WPA2-PSK加密 WPA2 的破解方式: 1 爆力破解 2,pin 破解 1) 先破解 pin 码 2)再用 minidwep-gtk 破解

  3. G - Preparing for Exams

    题目链接: https://vjudge.net/contest/251958#problem/G 具体思路: 圆内四边形内角互补,所以,如图所示. 证明,三角形oda和三角形obc相似. 第一步,角 ...

  4. Gaussian discriminant analysis 高斯判别分析

    高斯判别分析(附Matlab实现) 生成学习算法 高斯判别分析(Gaussian Discriminant analysis,GDA),与之前的线性回归和Logistic回归从方法上讲有很大的不同,G ...

  5. AOP Schema配置

    AOP(Aspect-Oriented Programming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入封装.继承和 ...

  6. cf1060D&period; Social Circles&lpar;贪心&rpar;

    题意 题目链接 Sol 我是这样考虑的:从大到小考虑每个\(l, r\),最大的\(l\)应该和最大的\(r\)匹配(不然就亏了),其次次大的\(r\)应该和次大的\(l\)匹配 然后就过了.. /* ...

  7. 使用pug&lpar;jade&rpar;&comma;以及在vue&plus;webpack中使用pug&lpar;jade&rpar;

    一:在HTML中使用pug 在css中有预处理器less和scss来使我们的样式表更加的简介,那么在HTML中有没有这样的格式呢,答案是有的,那就是pug(前身是jade),效果如下: 转译以后 好, ...

  8. 【英语】Bingo口语笔记&lpar;85&rpar; - ain&comma;ane读法

  9. &lbrack;BZOJ2527&rsqb;Meteors

    整体二分挺好玩的...学一发 这个询问显然是可以二分的,但每次都二分就会T爆,所以我们有了“整体”二分 每次处理一些询问,要求这些询问的答案一定在$[l,r]$中 先把$l$到$mid$的操作实施,那 ...

  10. HTML ui ol dl

    <!-- 超链接target的属性 _blank 在新窗体中打开被链接文档. _self 默认. 在同样的框架中打开被链接文档. _parent 在父框架集中打开被链接文档. _top 在整个窗 ...