zoukankan      html  css  js  c++  java
  • .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

      

  • 相关阅读:
    Spring配置文件中指定init-method属性的作用
    Spring中的InitializingBean接口
    java中的instanceof用法
    mybatis中useGeneratedKeys和keyProperty的作用
    (转载)springboot集成httpinvoker的客户端
    (转载)spring 之间的远程调用-Spring Http调用的实现
    (转载)maven profile多环境自动切换配置
    (转载)使用Maven构建多模块项目
    python3 之logging模块
    python3之编码
  • 原文地址:https://www.cnblogs.com/cnki/p/5686268.html
Copyright © 2011-2022 走看看