多线程进阶代码三

  1. // @ 来源于挽留刀的技术系列文章-C#的多线程机制探索
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Collections;
  7. using System.Threading;
  8. namespace MutiThread
  9. {
  10.     /* 在多线程的程序中,经常会出现两种情况。一种情况下,应用程序中的线程
  11.      * 把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应;
  12.      * 而另外一种情况则是线程平常都处于休眠状态,只是周期性地被唤醒。
  13.      * 在.net framework里边,我们使用ThreadPool来对付第一种情况,使用Timer
  14.      * 来对付第二种情况。本例就是ThreadPool的实例,Timer的实例参看Program4*/
  15.     /* ThreadPool类也是一个静态类,你无需自己建立线程,只需把你要做的工作写
  16.      * 成函数,然后作为参数传递给ThreadPool.QueueUserWorkItem()方法就行了,
  17.      * 传递的方法就是依靠WaitCallback代理对象,而线程的建立、管理、运行等等
  18.      * 工作都是由系统自动完成的,你无须考虑那些复杂的细节问题
  19.      * 就好像你是公司老板——只需要安排工作,而不必亲自动手。*/
  20.     //这是用来保存信息的数据结构,将作为参数被传递
  21.     public class SomeState
  22.     {
  23.         public int Cookie;
  24.         public SomeState(int iCookie)
  25.         {
  26.             Cookie = iCookie;
  27.         }
  28.     }
  29.     public class Alpha
  30.     {
  31.         public Hashtable HashCount;
  32.         // ManualResetEvent允许线程通过发信号互相通信,此通信涉及一个线程在其他线程进行之前必须完成的任务,相当于一个信号灯,可以利用它的信号来通知其它线程.
  33.         public ManualResetEvent eventX;
  34.         public static int iCount = 0;
  35.         public static int iMaxCount = 0;
  36.         public Alpha(int MaxCount)
  37.         {
  38.             HashCount = new Hashtable(MaxCount);
  39.             iMaxCount = MaxCount;
  40.         }
  41.         // 线程池里的线程将调用Beta()方法
  42.         public void Beta(Object state)
  43.         {
  44.             // 输出当前线程的hash编码值和Cookie的值
  45.             Console.WriteLine(" {0} {1} :", Thread.CurrentThread.GetHashCode(), ((SomeState)state).Cookie);
  46.             Console.WriteLine("HashCount.Count=={0}, Thread.CurrentThread.GetHashCode()=={1}", HashCount.Count, Thread.CurrentThread.GetHashCode());
  47.             lock (HashCount)
  48.             {
  49.                 // 如果当前的Hash表中没有当前线程的Hash值,则添加之
  50.                 if (!HashCount.ContainsKey(Thread.CurrentThread.GetHashCode()))
  51.                 {
  52.                     HashCount.Add(Thread.CurrentThread.GetHashCode(), 0);
  53.                 }
  54.                 HashCount[Thread.CurrentThread.GetHashCode()] = ((int)HashCount[Thread.CurrentThread.GetHashCode()]) + 1;
  55.             }
  56.             // 将当前线程挂起指定的时间
  57.             int iX = 2000;
  58.             Thread.Sleep(iX);
  59.             /* Interlocked类为多个线程共享的变量提供原子操作,因为增加变量操作不
  60.              * 是一个原子操作,可看成三个步骤来完成(可在msdn中Interlocked类的内容),
  61.              * 以防当前线程在执行完前两个步骤后而被其他线程抢先 */
  62.             // Interlocked.Increment()以原子操作的形式递增指定变量的值并存储结果
  63.             Interlocked.Increment(ref iCount);
  64.             if (iCount == iMaxCount)
  65.             {
  66.                 Console.WriteLine();
  67.                 Console.WriteLine("Setting eventX ");
  68.                 // Set()将事件状态设置为终止状态,允许等待线程继续;Reset()将事件状态设置为非终止状态,从而导致等待线程线程受阻 
  69.                 eventX.Set();
  70.             }
  71.         }
  72.     }
  73.     public class SimplePool
  74.     {
  75.         public static int Main(string[] args)
  76.         {
  77.             Console.WriteLine("Thread Pool Sample:");
  78.             bool W2K = false;
  79.             int MaxCount = 10;// 允许线程池中运行最多10个线程
  80.             // 新建ManualResetEvent对象并且初始化为无信号状态
  81.             ManualResetEvent eventX = new ManualResetEvent(false);
  82.             Console.WriteLine("Queuing {0} items to Thread Pool", MaxCount);
  83.             Alpha oAlpha = new Alpha(MaxCount); // 创建工作项
  84.             // 注意初始化oAlpha对象的eventX属性
  85.             oAlpha.eventX = eventX;
  86.             Console.WriteLine("Queue to Thread Pool 0");
  87.             try
  88.             {
  89.                 // 将工作项装入线程池 
  90.                 // 这里要用到Windows 2000以上版本才有的API,所以可能出现NotSupportException异常
  91.                 ThreadPool.QueueUserWorkItem(new WaitCallback(oAlpha.Beta),
  92.                 new SomeState(0));
  93.                 W2K = true;
  94.             }
  95.             catch (NotSupportedException)
  96.             {
  97.                 Console.WriteLine("These API's may fail when called on a non-Windows 2000 system.");
  98.                 W2K = false;
  99.             }
  100.             if (W2K)// 如果当前系统支持ThreadPool的方法.
  101.             {
  102.                 for (int iItem = 1; iItem < MaxCount; iItem++)
  103.                 {
  104.                     // 插入队列元素
  105.                     Console.WriteLine("Queue to Thread Pool {0}", iItem);
  106.                     ThreadPool.QueueUserWorkItem(new WaitCallback(oAlpha.Beta), new SomeState(iItem));
  107.                 }
  108.                 Console.WriteLine("Waiting for Thread Pool to drain");
  109.                 // 使当前主线程挂起,等待事件的完成,即线程调用ManualResetEvent.Set()方法
  110.                 eventX.WaitOne(Timeout.Infinite, true);
  111.                 // WaitOne()方法使调用它的线程等待直到eventX.Set()方法被调用
  112.                 Console.WriteLine("Thread Pool has been drained (Event fired)");
  113.                 Console.WriteLine();
  114.                 Console.WriteLine("Load across threads");
  115.                 foreach (object o in oAlpha.HashCount.Keys)
  116.                 {
  117.                     Console.WriteLine("{0} {1}", o, oAlpha.HashCount[o]);
  118.                 }
  119.             }
  120.             Console.ReadLine();
  121.             return 0;
  122.         }
  123.     }
  124. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值