通过多线程,c#能够并行执行代码。每一个线程都有它独立的执行路径,所有的线程都能够访问共有的变量。下面的例子说明这个问题:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Timers; using System.Threading; using System.Threading.Tasks; namespace ThresdScript { class MainClass { static string str = ""; static void Main(string[] args) { Thread t1 = new Thread(Add1); t1.Start(); Thread t2 = new Thread(Add2); t2.Start(); //等待一段时间 Thread.Sleep(1000); Console.WriteLine( str ); Console.ReadKey(); } //线程1 public static void Add1() { for (int i = 0; i < 20; i++) { Thread.Sleep(10); str += 'a'; } } //线程2 public static void Add2() { for (int i = 0; i < 20; i++) { for (int j = 0; j < 20; j++) { Thread.Sleep(10); str += 'b'; } } } } }
由于两个线程并行执行,字符串str时而被Add1操作,时而被Add2操作,所以打印如下结果:
线程互斥.png
为了避免线程竞争,可以通过加锁的方式(Lock)来处理,当2个线程争夺一个锁的时候,只能有一个线程有资格获取,另一个挂起等待。一直等到可用为止,这种情况,保证在同一时刻只有一个线程能进入临界区。程序改为下面的状态:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Timers; using System.Threading; using System.Threading.Tasks; namespace ThresdScript { class MainClass { static string str = ""; static void Main(string[] args) { Thread t1 = new Thread(Add1); t1.Start(); Thread t2 = new Thread(Add2); t2.Start(); //等待一段时间 Thread.Sleep(1000); Console.WriteLine( str ); Console.ReadKey(); } //线程1 public static void Add1() { lock (str) { for (int i = 0; i < 20; i++) { Thread.Sleep(10); str += 'a'; } } } //线程2 public static void Add2() { lock (str) { for (int i = 0; i < 20; i++) { Thread.Sleep(10); str += 'b'; } } } } }
运行后的2种情况:
第一种.png
第二种.png
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句