线程池ThreadPool

发布时间 2023-09-27 11:13:41作者: 骑牛射雕
1什么是线程池?

ThreadPool 类

  • 命名空间:System.Threading

  • 程序集:System.Threading.ThreadPool.dll

提供一个线程池,该线程池可用于执行任务、发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。

 

* 通过线程池创建的线程默认为后台线程,优先级默认为Normal。

 

2为什么用到线程?

 

上篇文章介绍了Thread的例子,但在实际开发中使用的线程往往是大量的和更为复杂的,每新建一个线程都需要占用内存空间和其他资源,而新建了那么多线程,有很多在休眠,或者在等待资源释放;又有许多线程只是周期性的做一些小工作,如刷新数据等等,太浪费了,划不来,实际编程中大量线程突发,然后在短时间内结束的情况很少见。于是,为此引入了线程池的概念。

 

好处

  1、减少在创建和销毁线程上所花的时间以及系统资源的开销 ①
  2、如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存以及”过度切换”。

 

① 线程池中的线程执行完指定的方法后并不会自动消除,而是以挂起状态返回线程池,如果应用程序再次向线程池发出请求,那么处以挂起状态的线程就会被激活并执行任务,而不会创建新线程,这就节约了很多开销。只有当线程数达到最大线程数量,系统才会自动销毁线程。因此,使用线程池可以避免大量的创建和销毁的开支,具有更好的性能和稳定性,其次,开发人员把线程交给系统管理,可以集中精力处理其他任务。

 

4什么时候使用多线程?

 

1、并发运行若各个运行时间不长且互不干扰的任务
2、需要处理的任务的数量大 

线程池最多管理线程数量=“处理器数 * 250”。也就是说,如果您的机器为2个2核CPU,那么CLR线程池的容量默认上限便是1000。
5如何使用线程台线程

 

其实线程池使用起来很简单,常见函数如下

a.设置线程池最大最小:
// workerThreads:要由线程池根据需要创建的新的最小工作程序线程数。
// completionPortThreads:要由线程池根据需要创建的新的最小空闲异步 I/O 线程数。
// 返回结果:如果更改成功,则为 true;否则为 false。
[SecuritySafeCritical]
public static bool SetMinThreads(int workerThreads, int completionPortThreads);
ThreadPool.SetMaxThreads(1,1)
// workerThreads:线程池中辅助线程的最大数目。
// completionPortThreads: 线程池中异步 I/O 线程的最大数目。
// 返回结果:如果更改成功,则为 true;否则为 false。
[SecuritySafeCritical]
public static bool SetMaxThreads(int workerThreads, int completionPortThreads);
ThreadPool.SetMaxThreads(5,5)

 

设置可以同时处于活动状态的线程池的请求数目。所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。还可以设置最小线程数。

b.将任务添加进线程池:
ThreadPool.QueueUserWorkItem(new WaitCallback(方法名));

ThreadPool.QueueUserWorkItem(new WaitCallback(方法名), 参数);

 

6举例说明

 

 

运行结果如下:

 

 

每次运行的结果都不相同,上边代码把 Console.ReadKey(); 注释后,程序只执行了二个线程便退出,代表线程池本身为后台线程。

 

 

当我们需要知道 ThreadPool 什么时候终止时,可以利用信号灯AutoResetEvent和ManualResetEvent来解决问题。

 



运行结果如下: