一: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 ///55 /// 建房子第一道所需要的工序56 /// 57 /// 58 static void BuilderHourseStep1(string person)59 {60 try61 {62 Console.WriteLine(string.Format("『{0}』BuilderHourseStep1....", person));63 }64 finally65 {66 cde.Signal();//建造完成一点后,通知监工67 }68 }69 ///70 /// 建房子第二道所需要的工序71 /// 72 /// 73 static void BuilderHourseStep2(string person)74 {75 try76 {77 Console.WriteLine(string.Format("『{0}』BuilderHourseStep2.....", person));78 }79 finally80 {81 cde.Signal();82 }83 }84 ///85 /// 建房子第三道所需要的工序86 /// 87 /// 88 static void BuilderHourseStep3(string person)89 {90 try91 {92 Console.WriteLine(string.Format("『{0}』BuilderHourseStep3.......", person));93 }94 finally95 {96 cde.Signal();97 }98 }99 }
分步执行任务
1 static void Main(string[] args) 2 { 3 IListtaskList =new List { "任务一","任务二", "任务四", "任务五", "任务六" }; 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