C# 多线程二:原子操作Interlocked 互锁的理解和简单示例

news/2024/11/24 14:02:47/

一.多线程的线程安全

多线程安全问题原因是在cpu执行多线程时,在执行的过程中可能随时切换到其他的线程上执行,当多个线程同时操作同一个变量时,如果不施加其他措施,可能导致错误数据的出现

二.Interlocked的特点

Interlocked是为多个线程共享的变量提供原子操作,这个类是一个静态类 它提供了以线程安全的方式递增、递减、交换和读取值的方法。

它的特点是:
(1)、相对于其他线程同步技术,速度会快很多。(它的原子操作是基于CPU本身的,非阻塞的,所以要比lock的效率高。)


(2)、只能用于简单的同步问题。(数学运算操作仅限于Increment、Decrement以及Add)

三.什么是原子操作

 如果一条语句在底层处理器上被当作一个独立不可分割的指令,那么它本质上是原子的(atomic)。严格的原子性可以阻止任何抢占的可能对于 32 位(或更低)的字段的简单读写总是原子的
      而操作 64 位字段仅在 64 位运行时环境下是原子的,并且结合了多个读写操作的语句必然不是原子的.

 32位和64位代表cpu一次处理数据的能力是32位还是64位,由前一章我们所理解的多线程的运行原理 可以轻易的得出当32位机器操作64位字段,如果此时发生了时间片轮询,则此时对64位的操作就不是原子操作

四.Interlocked的方法和作用

Interlocked的方法和作用
方法作用
CompareExchange()安全比较两个值是不是相等。如果相等,将第三个值于其中一个值交换
Decrement()安全递减1,相当于 i--
Exchange()安全交换:把值2赋给值1;返回新值
Increment()安全递加1,相当于 i++
Add()安全相加一个数值,相当于 a = a + 3
Read()安全读取数值,相等于int a=b

五.Interlocked的简单使用

1.不使用Interlocked

代码:

public class LudwigInterlocked {string persion;public LudwigInterlocked() {persion = "没人啊?";}public void AddPersion(string name) {persion = name;}public string SubPersion() {return persion;}
}
class Program {static string[] names = new string[] { "小明", "小话", "小雅", "小斌", "小头"};static void Main(string[] args) {LudwigInterlocked ludwigInterlocked = new LudwigInterlocked();ThreadStart threadStart = new ThreadStart(() => {for(int i = 0; i < names.Length; i++) {ludwigInterlocked.AddPersion(names[i]);Thread.Sleep(10);}});Thread thread = new Thread(threadStart);thread.Start();Thread.Sleep(10);Thread thread1 = new Thread(() => {for(int i = 0; i < names.Length; i++) {string name = ludwigInterlocked.SubPersion();if(!string.IsNullOrEmpty(name)) {Console.WriteLine(name);Thread.Sleep(10);}}});thread1.Start();Console.Read();}
}

 打印:

我们发现当两个线程同时操作同一个变量时,出现了我们不想要的结果。

2.使用Interlocked

 代码:

public class LudwigInterlocked {string persion;long index;public LudwigInterlocked() {persion = "没人啊?";}public void AddPersion(string name) {while(Interlocked.Read(ref index) == 1) {Thread.Sleep(10);}Interlocked.Increment(ref index);persion = name;}public string SubPersion() {while(Interlocked.Read(ref index) == 0) {Thread.Sleep(10);}Interlocked.Decrement(ref index);return persion;}
}
class Program {static string[] names = new string[] { "小明", "小话", "小雅", "小斌", "小头"};static void Main(string[] args) {LudwigInterlocked ludwigInterlocked = new LudwigInterlocked();ThreadStart threadStart = new ThreadStart(() => {for(int i = 0; i < names.Length; i++) {ludwigInterlocked.AddPersion(names[i]);Thread.Sleep(10);}});Thread thread = new Thread(threadStart);thread.Start();Thread.Sleep(10);Thread thread1 = new Thread(() => {for(int i = 0; i < names.Length; i++) {string name = ludwigInterlocked.SubPersion();if(!string.IsNullOrEmpty(name)) {Console.WriteLine(name);Thread.Sleep(10);}}});thread1.Start();Console.Read();}
}

打印:

利用Interlocked达到了我们想要的效果,这个例子中的index使用了Interlocked 进行操作,虽然被多个线程操作,仍然不会出现线程安全的问题。


http://www.ppmy.cn/news/171768.html

相关文章

小话 Spring AOP 源码

在上篇 Spring AOP 简单使用 中简单介绍了 AOP 相关概念和使用&#xff0c;这篇将要按照注解驱动的 Spring 来进行 AOP 源码的学习分享&#xff0c;欢迎阅读斧正。 通过下面的源码分析&#xff0c;会了解到 Spring AOP 有两种实现方式&#xff0c;一个是 JDK 自带的&#xff0c…

C语言余数为0输出intact,小话c语言

汇编和c只有一步之近----小话c语言(19) 作者&#xff1a;陈曦 日期&#xff1a;2012-6-810:50:13 环境&#xff1a;[Ubuntu11.04 Intel-based x64 gcc4.5.2 CodeBlocks10.05 AT&T汇编 Intel汇编] 转载请注明出处 Q&#xff1a;举个例子吧。 A&#xff1a;下面的代码的目…

C# 多线程四:互斥量Mutex的简单理解与运用

目录 一. 特点&#xff1a; 1.非静态类继承 2.可以跨进程 二.构造函数 1.Mutex() 2.Mutex(Boolean) 2. Mutex(Boolean, String) 3.Mutex(Boolean, String, Boolean) 三.方法 一. 特点&#xff1a; 1.非静态类继承 Object->MarshalByRefObject->WaitHandle->…

坚持#第369天~知道了惠普打印机和佳能打印机打印不清晰了怎么解决

如何给惠普打印机加碳粉&#xff1f;武汉东丰我看的是别人拆开硒鼓加粉&#xff0c;沈阳这边买的是绘威硒鼓cc388A和绘威碳粉cc388A标配易加粉版适用于东丰惠普M1136打印机&#xff0c;加碳粉步骤:戴上一次性手套&#xff0c;倒废粉口和加粉口磕几下倒干净&#xff0c;然后将碳…

佳能IR2520I远程扫描怎么用

1、首先连网线&#xff0c;在一体机上设置好IP&#xff0c;ping测试正常。 2、安装好Color Network ScanGear 2 Tool后&#xff0c;设置连接成功如图 3、复印机处选择--其它--远程扫描--在线 4、电脑打开windows自带的扫描软件&#xff0c;找不到可以在运行中输入wiaacmgr.exe …

canon 打印机 android,Canon PRINT Inkjet/SELPHY

一款专为匹配佳能打印机扫描仪设计的Canon PRINT Inkjet/SELPHY安卓版app&#xff0c;下载Canon PRINT安卓版即可使用手机远程控制打印操作。 软件介绍 Canon PRINT Inkjet/SELPHY是一款免费应用程序&#xff0c;让安卓智能手机或平板用户享用PIXMA, MAXIFY和SELPHY的打印、扫描…

佳能PIXMAnbsp;MP150/MP170/MP450打印…

佳能PIXMA MP150/MP170/MP450打印机PG-40、CL-41墨盒的加墨方法 佳能PIXMA-IP1200、IP1600、IP2200、IP6210D、IP6220D、MP150、MP170、MP450等均使用的PG-40、CL-41墨盒&#xff0c;都可按照如下加墨方法。 PG-40、CL41墨盒的加墨方法 &#xff08;1&#xff09; 黑色的墨盒…

惠普P1100 series “打印机安装失败,未安装打印机”问题解决方法

记一次罕见的惠普打印机驱动安装失败的解决方案 在新组装电脑上使用官方驱动安装惠普P1108驱动时&#xff0c;一直出现“打印机安装失败&#xff0c;未安装打印机”的问题。 首先&#xff0c;我尝试了在“设备管理器”-“其他设备”-“更新驱动”&#xff0c;出现“打印机驱动…