通过学习Quartz.NET源码,了解其线程池ThreadPool实现。
有3种线程池,分别为DedicatedThreadPool、DefaultThreadPool、ZeroSizeThreadPool。
DedicatedThreadPool、DefaultThreadPool为TaskSchedulingThreadPool子类,两者调度器不一样,TaskSchedulingThreadPool抽象类实现IThreadPool;ZeroSizeThreadPool类实现IThreadPool。
一、TaskSchedulingThreadPool
1.1、SemaphoreSlim
控制线程池可以分配最大并发数
1.2、CountdownEvent
统计线程实际分配并发数、判断任务是否执行完成。
1.3、执行任务
获取可执行并发、设置实际执行并发、包裹委托任务调用调度器、执行完成释放并发。
task.Start(Scheduler)会走到调度器QueueTask方法。
1.4、任务关闭
取消执行、等待已分配任务执行完毕
1.5、获取当前可分配并发
1.6、与QuartzSchedulerThread类交互
QuartzSchedulerThread创建下一批次要执行任务时根据获取线程池当前可分配并发,与最大批处理大小比较取最小值,获取下一个时间点的待执行的任务。
进一步封装任务后,调用线程池的RunInThread添加任务。
二、DedicatedThreadPool(专用线程池)
使用任务调度器为QueuedTaskScheduler。线程池最大并发走基类实现控制。
2.1、QueuedTaskScheduler(排队任务调度器)
通过线程安全的BlockingCollection集合的生产消费者模式执行Task。
创建BlockingCollection集合,多个Thread:
生产Task,被线程池task.Start(Scheduler)调用:
消费执行Task:
2.2、QueuedTaskScheduler另外2个应用场景
ClusterManager(集群管理)、MisfireHandler(未触发处理器)中通过创建1个线程的QueuedTaskScheduler,Task.Factory.StartNew使用。
三、DefaultThreadPool(默认线程池)
使用任务调度器为.net 默认调度器:TaskScheduler.Default。线程池最大并发走基类实现控制。
四、ZeroSizeThreadPool(零大小线程池)
永远不会执行作业;使用零大小线程池,仅用于数据库管理节点。