相关动态
C#多线程同步的几种方法
2024-12-07 22:19
C#多线程同步的几种方法 种方法 C#多线程同步的几种方法

1.为什么使用同步

多线程操作的时候我们知道要避免线程之间共享数据,但是很多时候我们要使用多线程并且还要访问同一块内存的数据,这是我们就必须要使用同步技术,确保一次只有一个线程访问和改变共享状态。

下面我就来说一下同步所用的几种方法。

2.Lock语句

lock是一种比较好用的简单的线程同步方式,它是通过为给定对象获取互斥锁来实现同步的。它是通过线程之间的互斥来达到同步效果的。用法如下

如果多个线程同时调用DoSomething方法时,我们又不希望线程同时能够执行该方法,在方法体中添加Lock语句后,这样一次只能有一个线程访问该方法。

Lock的参数使用要注意以下几点

1、不能是primitive type,比如int bool 等 

如果是int,那么传入时势必会发生装箱操作,这会导致每次lock的对象都不一样,就没办法实现多线程同步了。  2、最好不是public类的对象  如果是public类的对象,万一不知情的线程new出实例然后又对它加锁,就可能导致死锁。  3、不能是string的实例  c#中字符串都是在CLR暂留的,整个程序使用这个字符串的都是一个实例对象,如果有两个互不知情的线程对它加锁就会导致死锁了。  4、不能是函数的局部变量  如果函数内部声明一个变量int a,用lock(a)去锁这个函数的一段代码,多线程执行该段代码时都会产生新的a,就没办法告诉彼此是否在占用资源,也就无法实现同步。

3.Interlocked 类

Interlocked 类用于使变量的简单语句原子化。Interlocked 类提供了以线程安全的方式递增(Increment,递减(Decrement,交换(Exchange,读取值(CompareExchange)的方法。

不过也有人会说使用Lock也可以做到线程同步,为什么我们还要单独使用Interlocked 类呢?因为与其他同步技术相比,Interlocked 类会快的多。

 

4.Monitor 类

Lock关键字实际上是一个语法糖,它将Monitor对象进行封装,使用时调用了Enter()方法,该方法会一直等待,直到线程锁定对象为止。

与lock语句相比,Monitor 类的主要优点是:可以添加一个等待被锁定的超时值。这样就不会无限期的等待被锁定。

如果obj被锁定,TryEnter()方法就会把Mlock设为true,并同步地访问由对象obj锁定的状态。如果另一个线程锁定的obj超过500ms,TryEnter()就把遍历Mlock设置为false,线程不再等待,而是执行相关操作2。

5.SpinLock 类

如果Monitor开销由于垃圾回收而过高,则可以使用SpinLock 类(.NET 4.0开始引入)。SpinLock适用在有大量的锁定,且锁定的时间非常短。

6.WaitHandle 基类

在 WaitHandle类中SignalAndWait、WaitAll、WaitAny及WaitOne这几个方法都有重载形式,其中除WaitOne之外都是静态的。WaitHandle方法常用作同步对象的基类。WaitHandle对象通知其他的线程它需要对资源排他性的访问,其他的线程必须等待,直到WaitHandle不再使用资源和等待句柄没有被使用。

  WaitHandle方法有多个Wait的方法,这些方法的区别如下

  WaitAll:等待指定数组中的所有元素收到信号。

  WaitAny:等待指定数组中的任一元素收到信号。

  WaitOne:当在派生类中重写时,阻塞当前线程,直到当前的 WaitHandle 收到信号。

  这些wait方法阻塞线程直到一个或者更多的同步对象收到信号。

下面的代码示例演示当主线程使用 WaitHandle 类的静态 M:System.Threading.WaitHandle.WaitAny(System.Threading.WaitHandle[]) 和Waitall方法等待任务完成时,两个线程可以如何完成后台任务。

 

 

7.Mutex 类

Mutex与上述的Monitor比较接近,不过Mutex不具备Wait,Pulse,PulseAll的功能,因此,我们不能使用Mutex实现类似的唤醒的功能。不过Mutex有一个比较大的特点,Mutex是跨进程的,因此我们可以在同一台机器甚至远程的机器上的多个进程上使用同一个互斥体。尽管Mutex也可以实现进程内的线程同步,而且功能也更强大,但这种情况下,还是推荐使用Monitor,因为Mutex类是win32封装的,所以它所需要的互操作转换更耗资源。使用方法如下

8.Semaphore 类

Semaphore 类用于限制访问某资源的线程数量,类似互斥锁。

通过使用一个计数器来控制对共享资源的访问,如果计数器大于0,就允许访问,如果等于0,就拒绝访问。计数器累计的是“许可证”的数目,为了访问某个资源。线程必须从信号量获取一个许可证。通常在使用信号量时,希望访问共享资源的线程将尝试获取一个许可证,如果信号量的计数器大于0,线程将获取一个许可证并将信号量的计数器减1,否则先线程将阻塞,直到获取一个许可证;当线程不再需要共享资源时,将释放锁拥有的许可证,并将许可证的数量加1,如果有其他的线程正在等待许可证,那么该线程将立刻获取许可证。

另外,允许同时访问的资源的进程数量是在创建信号量时指定的,如果创建一个允许进程访问的信号量数目为1,则该信号量就和互斥锁的用法一样。

9.ReaderWriterLockSlim 类

读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁。在C#中,推荐使用ReaderWriterLockSlim类来完成读写锁的功能。某些场合下,对一个对象的读取次数远远大于修改次数,如果只是简单的用lock方式加锁,则会影响读取的效率。而如果采用读写锁,则多个线程可以同时读取该对象,只有等到对象被写入锁占用的时候,才会阻塞。简单的说,当某个线程进入读取模式时,此时其他线程依然能进入读取模式,假设此时一个线程要进入写入模式,那么他不得不被阻塞。直到读取模式退出为止。同样的,如果某个线程进入了写入模式,那么其他线程无论是要写入还是读取,都是会被阻塞的。

进入写入/读取模式有2种方法

EnterReadLock尝试进入写入模式锁定状态。

TryEnterReadLock(Int32) 尝试进入读取模式锁定状态,可以选择整数超时时间。

EnterWriteLock 尝试进入写入模式锁定状态。

TryEnterWriteLock(Int32) 尝试进入写入模式锁定状态,可以选择超时时间。

退出写入/读取模式有2种方法

ExitReadLock 减少读取模式的递归计数,并在生成的计数为 0(零)时退出读取模式。

ExitWriteLock 减少写入模式的递归计数,并在生成的计数为 0(零)时退出写入模式。

代码示例如下

 

以上为几种线程同步方式,对于同步技术来说,还有很多种其他方式。能力有限,这里只介绍这几种。

    以上就是本篇文章【C#多线程同步的几种方法】的全部内容了,欢迎阅览 ! 文章地址:http://ww.kub2b.com/news/2763.html
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 企库往资讯移动站 http://ww.kub2b.com/mobile/ , 查看更多   
最新文章
Shams:如果火箭季后赛早早被淘汰 他们很可能会积极追求杜兰特
直播吧04月17日讯 今日ESPN名记Shams Charania做客节目《NBA COUNTDOWN》中谈到了火箭追逐KD的可能性。Shams表示:“如果球队能
手机是什么时候出现的手机是哪个国家发明的「手机是什么时候出现的」
手机,这个如今几乎人手一部的通讯工具,其发展历程漫长而有趣。要追溯其起源,我们需要回到上世纪初。一、早期探索阶段早在20世
再建新厂、增加注资、积极纳税 北京税企协同共建优质营商环境
4月16日,北京市税务局“民企显身手”系列媒体采访活动正式启动。此次活动以“政策落实有力度、服务升级有温度、营商环境有厚度
oppo手机里的记事本在哪里手机记事本在哪里「oppo手机里的记事本在哪里」
“盾牌”是古代作战时一种手持格挡,用以掩蔽身体,抵御敌方兵刃、矢石等兵器进攻的防御性兵械,呈长方形或圆形,盾的中央向外凸
个人业务利润降30%,3万亿规模宁波银行也有“烦恼”
文 | 刘振涛资本市场进入财报披露季,上市企业过去一年的成绩令市场高度关注,特别是市场“分红大户”——上市银行的成绩备受关
闽北从观光到沉浸 解锁旅游新体验
  中新网南平4月17日电 (记者 张丽君)依托核心景区武夷山,闽北南平凭借创新的文旅融合模式,实现了从传统观光游到沉浸式深度
重新定义奢华旅游,情绪价值比“钞能力”更重要
【文/观察者网 王勇 编辑/赵乾坤】新加坡“亚洲新闻台”日前报道称,越来越多的千禧一代、Z世代以及来自亚洲和中东等新兴市场的
最便宜的红米手机——红米7A红米手机预定「最便宜的红米手机——红米7A」
5.28号下午,在红米K20系列发布会上,出现了一款史上最便宜的红米手机——红米 7A,售价仅549元起,如此便宜的手机究竟配置如何呢
如何开启手机定位功能,确保精准定位与安全使用手机定位功能在哪里开启「如何开启手机定位功能,确保精准定位与安全使用」
检查手机设置:在设定中找到“隐私”或“位置服务”选项。对于不同品牌的手机,可能会有所不同。例如,iPhone 在设置中有明显的
华为一键测速手机测速「华为一键测速」
华为一键测速有了这款app你就可以实时了解自己的网速了,更为专业强大的技术支撑,还能直接查看网络的各方面信息,各位朋友们尽

loading