一: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[] { "Yan", "Zhi", "wei", "Do", "Work" };
  13. //建房子第二期工人
  14. string[] _bhPerson2 = new string[] { "Yan2", "Zhi2", "wei2" };
  15. //建房子第三期工人
  16. string[] _bhPerson3 = new string[] { "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

  

并行编程之CountdownEvent的用法的更多相关文章

  1. 并行编程之PLINQ

    并行编程之PLINQ 并行 LINQ (PLINQ) 是 LINQ 模式的并行实现.PLINQ 的主要用途是通过在多核计算机上以并行方式执行查询委托来加快 LINQ to Objects 查询的执行速 ...

  2. .Net并行编程之二:并行循环

    本篇内容主要包括: 1.能够转化为并行循环的条件 2.并行For循环的用法:Parallel.For 3.并行ForEach的用法Parallel.ForEach 4.并行LINQ(PLINQ)的用法 ...

  3. Java并发编程之CountDownLatch的用法

    一.含义 CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能.CountDownLatch是一个同步的辅助类,它可以允许一个或多个线程等待, ...

  4. Pthreads并行编程之spin lock与mutex性能对比分析(转)

    POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API.线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段,其中最典型的应用 ...

  5. Shell编程之Shift的用法

    位置参数可以用shift命令左移.比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1.$2.$3丢弃,$0不移动.不带参数的shift命令相当于shift 1. 非常 ...

  6. Python网络编程之TCP套接字简单用法示例

    Python网络编程之TCP套接字简单用法示例 本文实例讲述了Python网络编程之TCP套接字简单用法.分享给大家供大家参考,具体如下: 上学期学的计算机网络,因为之前还未学习python,而jav ...

  7. 异步编程之Promise(3):拓展进阶

    异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...

  8. 深入浅出Cocoa多线程编程之 block 与 dispatch quene

    深入浅出 Cocoa 多线程编程之 block 与 dispatch quene 罗朝辉(http://www.cppblog.com/kesalin CC 许可,转载请注明出处 block 是 Ap ...

  9. [Cocoa]深入浅出Cocoa多线程编程之 block 与 dispatch quene

    深入浅出 Cocoa 多线程编程之 block 与 dispatch quene 罗朝辉(http://www.cppblog.com/kesalin CC 许可,转载请注明出处 block 是 Ap ...

随机推荐

  1. (转)Log4net 配置类库

    原文地址:http://blog.csdn.net/pfe_nova/article/details/20072137 1.单文件日志 对于单文件的日志,封装代码如下: public enum Log ...

  2. threading event

    #!usr/bin/env python 2 #coding: utf-8 3 #Author: Andy 4 5 import threading 6 import time 7 8 def pro ...

  3. Codeforces Round #218 (Div. 2) C. Hamburgers

    C. Hamburgers time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  4. MFC获取文本框字符串

    //方法1:使用用GetDlgItem,得到控件对像, 再GetWindowText //GetDlgItem(IDC_EDIT1)->GetWindowText() //方法2:控件与对应类关 ...

  5. docker 1.12设置非https访问registry

    升级docker到1.12后,发现使用原来的/etc/sysconfig/docker文件中设置--insecure-registry的方式,访问registry失败,提示"http: se ...

  6. 国内外CDN服务商CNAME特征串调研

    总结 此篇博文给特定需求的人群使用,通过CNAME的某些特征串,确定其使用的是哪家CDN,大多是国外的CDN,国内的CDN厂商只有几个,格式为:[来源地址]+[截图]+[猜测的特征串],整体博文较长, ...

  7. 学习总结 java 创建及其练习

    创建: 打开eclipse—文件—新建—java项目—项目名称命名—点击texe-1练习下拉箭头—右击src—新建—类—设置类名称(名称设置时不要添加空格),在“想要创建哪些方法跟”下面点击:publ ...

  8. CI 自动提交表单

    //coontrol $this->load->view ( '/' . $this->index_lang ['FOLDER'] . '/eprepag_form.php', $p ...

  9. Oracle笔记 十三、PL/SQL面向对象之package

    --将方法和过程用包定义 create or replace package pkg_emp as --输入员工编号查询出员工信息 procedure pro_findInfo( in_empno e ...

  10. JS常用的设计模式(15)—— 职责链模式

    职责链模式是一个对象A向另一个对象B发起请求,如果B不处理,可以把请求转给C,如果C不处理,又可以把请求转给D.一直到有一个对象愿意处理这个请求为止. 打个比方,客户让老板写个php程序.老板肯定不写 ...