浅谈.NET下的多线程和并行计算(六)线程池基础 下

这节我们按照线程池的核心思想来自定义一个简单的线程池:

1) 池中使用的线程不少于一定数量,不多于一定数量

2) 池中线程不够的时候创建,富裕的时候收回

3) 任务排队,没有可用线程时,任务等待

我们的目的只是实现这些“需求”,不去考虑性能(比如等待一段时间再去创建新的线程等策略)以 及特殊的处理(异常),在实现这个需求的过程中我们也回顾了线程以及线程同步的基本概念。

首先,把任务委托和任务需要的状态数据封装一个对象:

public class WorkItem
{
   public WaitCallback Action { get; set; }
   public object State { get; set; }

   public WorkItem(WaitCallback action, object state)
   {
     this.Action = action;
     this.State = state;
   }
}

然后来创建一个对象作为线程池中的一个线程:

public class SimpleThreadPoolThread
{
   private object locker = new object();
   private AutoResetEvent are = new AutoResetEvent(false);
   private WorkItem wi;
   private Thread t;
   private bool b = true;
   private bool isWorking;

   public bool IsWorking 
   {
     get
     {
       lock (locker)
       {
         return isWorking;
       }
     }
   }
   public event Action<SimpleThreadPoolThread> WorkComplete;

   public SimpleThreadPoolThread()
   {
     lock (locker)
     {
       // 当前没有实际任务
       isWorking = false;
     }
     t = new Thread(Work) { IsBackground = true };
     t.Start();
   }

   public void SetWork(WorkItem wi)
   {
     this.wi = wi;
   }

   public void StartWork()
   {
     // 发出信号
     are.Set();
   }

   public void StopWork()
   {
     // 空任务
     wi = null;
     // 停止线程循环
     b = false;
     // 发出信号结束线程
     are.Set();
   }

   private void Work()
   {
     while (b)
     {
       // 没任务,等待信号
       are.WaitOne();
       if (wi != null)
       {
         lock (locker)
         {
           // 开始
           isWorking = true;
         }
         // 执行任务
         wi.Action(wi.State);
         lock (locker)
         {
           // 结束
           isWorking = false;
         }
         // 结束事件
         WorkComplete(this);
       }
     }
   }

时间: 2024-09-13 09:57:43

浅谈.NET下的多线程和并行计算(六)线程池基础 下的相关文章

浅谈.NET下的多线程和并行计算(四)线程同步基础 下

回顾一下上次,我们讨论了lock/AutoResetEvent/ManualResetEvent以及Semaphore.这些用于线程同 步的结构叫做同步基元.同步基元从类型上可以分为锁定/通知/联锁三种.lock显然锁定方式,而且是独 占锁定,也就是在锁释放之前不能由其它线程获得. Semaphore也是一种锁定,只不过不是独占锁,可以 指定多少个线程访问代码块.AutoResetEvent和ManualResetEvent当然就是通知方式了,前者在通行之后 自动重置,后者需要手动重置.我们还看

浅谈java中异步多线程超时导致的服务异常_java

在项目中为了提高大并发量时的性能稳定性,经常会使用到线程池来做多线程异步操作,多线程有2种,一种是实现runnable接口,这种没有返回值,一种是实现Callable接口,这种有返回值. 当其中一个线程超时的时候,理论上应该不 影响其他线程的执行结果,但是在项目中出现的问题表明一个线程阻塞,其他线程返回的接口都为空.其实是个很简单的问题,但是由于第一次碰到,还是想了一些时间的.很简单,就是因为阻塞的那个线 程没有释放,并发量一大,线程池数量就满了,所以其他线程都处于等待状态. 附上一段自己写的调

5天不再惧怕多线程——第五天 线程池

说到多线程,不可不说线程池,C#中关于池的概念很多,今天来整理下ThreadPool的使用. 是的,如果你很懒,如果你的执行任务比较短,如果你不想对线程做更精细的控制,那么把这些繁琐的东西丢给线程池吧. 一:ThreadPool 好了,下面看看TheadPool下有哪些常用的方法. 1:GetMaxThreads,GetMinThreads 首先我们肯定好奇线程池到底给我们如何控制线程数,下面就具体的看一看. class Program { static void Main(string[] a

艾伟:C#多线程学习(四) 多线程的自动管理(线程池)

本系列文章导航 C#多线程学习(一) 多线程的相关概念 C#多线程学习(二) 如何操纵一个线程 C#多线程学习(三) 生产者和消费者 C#多线程学习(四) 多线程的自动管理(线程池) C#多线程学习(五) 多线程的自动管理(定时器) C#多线程学习(六) 互斥对象 在多线程的程序中,经常会出现两种情况: 一种情况: 应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应 这一般使用ThreadPool(线程池)来解决: 另一种情况:线程平时都处于休眠状态,只是周期性地被

浅谈.NET下的多线程和并行计算(十四)并行计算前言

之前的文章中我们介绍了如何在.NET下运用相关类库进行多线程编程的基础,我们知道.NET 4.0已经 正式推出了,带来的重要特性是并行库.本文就谈谈对并行计算的一些理解和看法.并行计算不是一个很 新的概念,其实它就是通过多线程把同一个任务分割成多个子任务并行的执行的过程..NET 4.0并行库不 但提供了这方面的支持,而且还封装了多线程开发的各种场景,使得我们不需要依赖Thread/同步基元等 "底层"的对象就可以进行多线程开发.没有.NET 4.0的并行计算库我们同样可以进行并行计算

浅谈.NET下的多线程和并行计算(一)前言

作为一个ASP.NET开发人员,在之前的开发经历中接触多线程编程的机会并不是很多,但是随着.NET 4.0的发布临近,我越来越感受到未来的1-2年中并行计算将会有很大的应用.于是决定通过写日志的方式 来总结一下.NET 3.5下的多线程编程进而引入.NET 4.0提供的新的并行库以及新的并行编程模式和编程的 思维方式. 个人觉得在日常的编程中对于ASP.NET程序员来说使用多线程编程不是很多,其实我们无时无刻不在享 受多线程的优势.首先,WEB服务器环境就是一个多线程环境,每一个请求都是独立的线

浅谈.NET下的多线程和并行计算(十).NET异步编程模型基础 上

谈多线程谈到现在,我们要明确多线程的一个好处是可以进行并行的运算(充分利用多核处理器,对 于桌面应用程序来说就更重要一点了,没有WEB服务器,利用多核只能靠自己),还有一个好处就是异步 操作,就是我们可以让某个长时间的操作独立运行,不妨碍主线程继续进行一些计算,然后异步的去返回 结果(也可以不返回).前者能提高性能是因为能利用到多核,而后者能提高性能是因为能让CPU不在等 待中白白浪费,其实异步从广义上来说也可以理解为某种并行的运算.在之前的这么多例子中,我们大多 采用手工方式来新开线程,之前也

浅谈.NET下的多线程和并行计算(九)Winform中多线程编程基础 下

在之前的文章中我们介绍过两种Timer和BackgroundWorker组件,在上文中我们提到过,强烈建议在UI 线程上操作控件,否则很容易产生人品问题.可以想到,上次介绍的两个Timer基于ThreadPool,回调方 法运行于不同于UI线程的新线程上,在这个方法中操作控件需要进行 Invoke或BeginInvoke.其实,还有 第三种System.Windows.Forms.Timer,它可以让回调事件在UI线程上执行,我们来做一个实验比较一下 System.Windows.Forms.T

浅谈.NET下的多线程和并行计算(十二)CLR via C#第三版阅读笔记(1)

最近此书出了第三版,在阅读此书线程部分的过程中有很多心得,补充了此前知识盲点,因此把这些 关键和重要的知识点汇集成日志文章并且纳入到这个系列中.顺便说一下,笔者喜欢这本书的原因是作者 作为微软顾问并没有按照MSDN的教条教大家怎么去用而是能说出很多自己的观点甚至很多是微软.NET框架 不够的地方,并给出自己的实现. 为什么说线程是比较昂贵的? 1)从内存上来说,(对于32位架构)每一个线程包含线程内核对象(700字节)/线程环境块(4KB)/ 内核堆栈(12KB)/用户堆栈(1MB).并且可以发