一:Barrier(屏障同步)
二:spinLock(自旋锁)
信号量
一:CountdownEvent
虽然通过Task.WaitAll()方法也可以达到线程同步的目的。
但是CountdownEvent更牛X之处在于我们可以动态的改变“信号计数”的大小,比如一会儿能够容纳8个线程,一下又4个,一下又10个,CountdownEvent给我们提供了可以动态修改的解决方案。
模拟建房子工序
1 public partial class Form1 : Form 2 { 3 public Form1() 4 { 5 InitializeComponent(); 6 } 7 8 static CountdownEvent cde = null; 9 private void button1_Click(object sender, EventArgs e) 10 { 11 //建房子第一期工人 12 string[] _bhPerson1 = new string[5] { "Yan", "Zhi", "wei", "Do", "Work" }; 13 //建房子第二期工人 14 string[] _bhPerson2 = new string[3] { "Yan2", "Zhi2", "wei2" }; 15 //建房子第三期工人 16 string[] _bhPerson3 = new string[3] { "Yan3", "Zhi3", "wei3" }; 17 using (cde = new CountdownEvent(Environment.ProcessorCount))//开始监管,相当于监工 18 { 19 cde.Reset(_bhPerson1.Length);//设置第一期建造需要5个人 20 foreach (string person in _bhPerson1) 21 { 22 Task.Factory.StartNew(() => 23 { 24 BuilderHourseStep1(person); 25 }); 26 27 } 28 cde.Wait();//等待第一期建造完成 29 Console.WriteLine("-----------------------"); 30 31 cde.Reset(_bhPerson2.Length);//设置第二期建需要三个人 32 foreach (string person in _bhPerson2) 33 { 34 Task.Factory.StartNew(() => 35 { 36 BuilderHourseStep2(person); 37 }); 38 } 39 cde.Wait();//等待第二期建造完成 40 Console.WriteLine("-----------------------"); 41 42 cde.Reset(_bhPerson3.Length);//设置第三期建需要三个人 43 foreach (string person in _bhPerson3) 44 { 45 Task.Factory.StartNew(() => 46 { 47 BuilderHourseStep3(person); 48 }); 49 } 50 cde.Wait();//等待第三期建造完成 51 Console.WriteLine("-----------------------"); 52 } 53 } 54 /// <summary> 55 /// 建房子第一道所需要的工序 56 /// </summary> 57 /// <param name="person"></param> 58 static void BuilderHourseStep1(string person) 59 { 60 try 61 { 62 Console.WriteLine(string.Format("『{0}』BuilderHourseStep1....", person)); 63 } 64 finally 65 { 66 cde.Signal();//建造完成一点后,通知监工 67 } 68 } 69 /// <summary> 70 /// 建房子第二道所需要的工序 71 /// </summary> 72 /// <param name="person"></param> 73 static void BuilderHourseStep2(string person) 74 { 75 try 76 { 77 Console.WriteLine(string.Format("『{0}』BuilderHourseStep2.....", person)); 78 } 79 finally 80 { 81 cde.Signal(); 82 } 83 } 84 /// <summary> 85 /// 建房子第三道所需要的工序 86 /// </summary> 87 /// <param name="person"></param> 88 static void BuilderHourseStep3(string person) 89 { 90 try 91 { 92 Console.WriteLine(string.Format("『{0}』BuilderHourseStep3.......", person)); 93 } 94 finally 95 { 96 cde.Signal(); 97 } 98 } 99 }
分步执行任务
1 static void Main(string[] args) 2 { 3 IList<string> taskList =new List<string> {"任务一","任务二", "任务四", "任务五", "任务六" }; 4 int count = taskList.Count; 5 using (CountdownEvent cde = new CountdownEvent(Environment.ProcessorCount)) 6 { 7 cde.Reset(count);//设置信号数 8 foreach (var item in taskList) 9 { 10 Task.Factory.StartNew(() => 11 { 12 Console.WriteLine("处理任务:"+item); 13 cde.Signal();//每次调用 Signal 时,信号计数都会递减 1。 14 }); 15 } 16 cde.Wait();// 在主线程上,对 Wait 的调用将会阻塞,直至信号计数为零。 17 Console.WriteLine("接下来开始做下一件事情"); 18 cde.Reset(count);//重置信号数 19 foreach (var item in taskList) 20 { 21 Task.Factory.StartNew(() => 22 { 23 Console.WriteLine("继续处理任务:" + item); 24 cde.Signal();//每次调用 Signal 时,信号计数都会递减 1。 25 }); 26 } 27 } 28 Console.ReadKey(); 29 }
二:SemaphoreSlim
三: ManualResetEventSlim
教程
http://blog.gkarch.com/threading/part5.html#the-parallel-class
http://www.cnblogs.com/huangxincheng/archive/2012/04/08/2437701.html
http://www.cnblogs.com/yaopengfei/p/8315212.html