.Net并行编程之同步机制

 一: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     }
View Code

 分步执行任务

 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         }
View Code

 二: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

  

原文地址:https://www.cnblogs.com/cnki/p/5686268.html