地址:https://www.cnblogs.com/scmail81/archive/2018/08/19/9503266.html

CLR线程池并不会在CLR初始化时立即建立线程,而是在应用程序要创建线程来运行任务时,线程池才初始化一个线程。
线程池初始化时是没有线程的,线程池里的线程的初始化与其他线程一样,但是在完成任务以后,该线程不会自行销毁,而是以挂起的状态返回到线程池。直到应用程序再次向线程池发出请求时,线程池里挂起的线程就会再度激活执行任务。
这样既节省了建立线程所造成的性能损耗,也可以让多个任务反复重用同一线程,从而在应用程序生存期内节约大量开销。

通过CLR线程池所建立的线程总是默认为后台线程,优先级数为ThreadPriority.Normal。

CLR线程池分为工作者线程(workerThreads)I/O线程(completionPortThreads)两种:

  • 工作者线程是主要用作管理CLR内部对象的运作,通常用于计算密集的任务。
  • I/O(Input/Output)线程主要用于与外部系统交互信息,如输入输出,CPU仅需在任务开始的时候,将任务的参数传递给设备,然后启动硬件设备即可。等任务完成的时候,CPU收到一个通知,一般来说是一个硬件的中断信号,此时CPU继续后继的处理工作。在处理过程中,CPU是不必完全参与处理过程的,如果正在运行的线程不交出CPU的控制权,那么线程也只能处于等待状态,即使操作系统将当前的CPU调度给其他线程,此时线程所占用的空间还是被占用,而并没有CPU处理这个线程,可能出现线程资源浪费的问题。如果这是一个网络服务程序,每一个网络连接都使用一个线程管理,可能出现大量线程都在等待网络通信,随着网络连接的不断增加,处于等待状态的线程将会很消耗尽所有的内存资源。可以考虑使用线程池解决这个问题。

  线程池的最大值一般默认为1000、2000。当大于此数目的请求时,将保持排队状态,直到线程池里有线程可用。

  使用CLR线程池的工作者线程一般有两种方式:

  • 通过ThreadPool.QueueUserWorkItem()方法;
  • 通过委托;

  要注意,不论是通过ThreadPool.QueueUserWorkItem()还是委托,调用的都是线程池里的线程。

通过以下两个方法可以读取和设置CLR线程池中工作者线程与I/O线程的最大线程数。

  1. ThreadPool.GetMax(out in workerThreads,out int completionPortThreads);
  2. ThreadPool.SetMax(int workerThreads,int completionPortThreads);

  若想测试线程池中有多少线程正在投入使用,可以通过ThreadPool.GetAvailableThreads(out in workThreads,out int conoletionPortThreads)方法。

方法 说明
GetAvailableThreads 剩余空闲线程数
GetMaxThreads 最多可用线程数,所有大于此数目的请求将保持排队状态,直到线程池线程变为可用
GetMinThreads 检索线程池在新请求预测中维护的空闲线程数
QueueUserWorkItem 启动线程池里得一个线程(队列的方式,如线程池暂时没空闲线程,则进入队列排队)
SetMaxThreads 设置线程池中的最大线程数
SetMinThreads 设置线程池最少需要保留的线程数

我们可以使用线程池来解决上面的大部分问题,跟使用单个线程相比,使用线程池有如下优点:

1、缩短应用程序的响应时间。因为在线程池中有线程的线程处于等待分配任务状态(只要没有超过线程池的最大上限),无需创建线程。

2、不必管理和维护生存周期短暂的线程,不用在创建时为其分配资源,在其执行完任务之后释放资源。

3、线程池会根据当前系统特点对池内的线程进行优化处理。

总之使用线程池的作用就是减少创建和销毁线程的系统开销。在.NET中有一个线程的类ThreadPool,它提供了线程池的管理。

ThreadPool是一个静态类,它没有构造函数,对外提供的函数也全部是静态的。其中有一个QueueUserWorkItem方法,它有两种重载形式,如下:

public static bool QueueUserWorkItem(WaitCallback callBack):将方法排入队列以便执行。此方法在有线程池线程变得可用时执行。

public static bool QueueUserWorkItem(WaitCallback callBack,Object state):将方法排入队列以便执行,并指定包含该方法所用数据的对象。此方法在有线程池线程变得可用时执行。

QueueUserWorkItem方法中使用的的WaitCallback参数表示一个delegate,它的声明如下:

public delegate void WaitCallback(Object state)

如果需要传递任务信息可以利用WaitCallback中的state参数,类似于ParameterizedThreadStart委托。

下面是一个ThreadPool的例子,代码如下:

using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;namespace ConsoleApp1
{class ThreadPoolDemo{public ThreadPoolDemo(){}public void Work(){ThreadPool.QueueUserWorkItem(new WaitCallback(CountProcess));ThreadPool.QueueUserWorkItem(new WaitCallback(GetEnvironmentVariables));}/// <summary>  /// 统计当前正在运行的系统进程信息  /// </summary>  /// <param name="state"></param>  private void CountProcess(object state){Process[] processes = Process.GetProcesses();foreach (Process p in processes){try{Console.WriteLine("进程信息:Id:{0},ProcessName:{1},StartTime:{2}", p.Id, p.ProcessName, p.StartTime);}catch (Win32Exception e){Console.WriteLine("ProcessName:{0}", p.ProcessName);}finally{}}Console.WriteLine("获取进程信息完毕。");}/// <summary>  /// 获取当前机器系统变量设置  /// </summary>  /// <param name="state"></param>  public void GetEnvironmentVariables(object state){IDictionary list = System.Environment.GetEnvironmentVariables();foreach (DictionaryEntry item in list){Console.WriteLine("系统变量信息:key={0},value={1}", item.Key, item.Value);}Console.WriteLine("获取系统变量信息完毕。");}}
}

using System;
using System.Threading;namespace ConsoleApp1
{class Program{static void Main(string[] args){ThreadPoolDemo tpd1 = new ThreadPoolDemo();tpd1.Work();Thread.Sleep(5000);Console.WriteLine("OK");Console.ReadLine();}}
}

转载于:https://www.cnblogs.com/zxtceq/p/10980480.html

C# ThreadPool类(线程池)相关推荐

  1. 线程池ThreadPool,线程池底层ThreadPoolExecutor方法七大参数,拒绝策略,以及实际开发中高并发下用到哪个线程池?

    为什么要用线程池 基本的三个线程池的底层就是ThreadPoolExecutor类 ExecutorService threadPool = Executors.newFixedThreadPool( ...

  2. Android通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比

    在加载大量数据的时候,经常会用到异步加载,所谓异步加载,就是把耗时的工作放到子线程里执行,当数据加载完毕的时候再到主线程进行UI刷新.在数据量非常大的情况下,我们通常会使用两种技术来进行异步加载,一是 ...

  3. Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比

    Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比 标签: AndroidAsyncTaskThreadPool异步加载view 2 ...

  4. ScheduledThreadPool 源码解析——定时类线程池是如何工作的

    文章目录 引言 一.ScheduledThreadPool 使用示例 1. 延时类的定时任务 `schedule` 2. 延时类,固定周期执行任务 `scheduleAtFixedRate` 3. 延 ...

  5. c# ThreadPool.QueueUserWorkItem线程池的应用

    示例,将数据分批 ,每次1000条放入线程池中执行 dt 是查询出来的DataTable 数据. public List<AtmTaskLogdetail> OrderKPI_New(Da ...

  6. 9,线程池 threadPool 与 线程池执行器 threadPoolExecutor

    待续 转载于:https://www.cnblogs.com/zyguo/p/4346378.html

  7. Android多线程:这是一份全面 详细的线程池(ThreadPool)讲解教程

    前言 对于多线程,大家应该很熟悉.但是,大家了解线程池吗? 今天,我将带大家全部学习关于线程池的所有知识. 目录 1. 简介 2. 工作原理 2.1 核心参数 线程池中有6个核心参数,具体如下 上述6 ...

  8. 线程池ThreadPool知识碎片和使用经验速记

    ThreadPool(线程池)大概的工作原理是,初始时线程池中创建了一些线程,当应用程序需要使用线程池中的线程进行工作,线程池将会分配一个线程,之后到来的请求,线程池都会尽量使用池中已有的这个线程进行 ...

  9. ThreadPool 线程池

    文章目录 ThreadPool 线程池 游泳池 线程池简介(三大方法,七大参数,四大策略) Executor类 线程池参数说明 拒绝策略(重点) Executors 线程池的方法与创建 newCach ...

最新文章

  1. 用AI加速物联网落地,安富利的客户洞察和解决之道
  2. array initization in matlab zeros(1000)
  3. citrix协议ICA技术原理
  4. Android RecyclerView封装下拉刷新与上拉加载更多
  5. 如何导出项目到本地_如何在win10中导入/导出组策略设置,这个技巧很实用
  6. 搭建redis主从结构
  7. OpenJDK 14 与 OpenJDK 8 及多个主要版本的性能基准测试对比
  8. [转][darkbaby]任天堂传——失落的泰坦王朝(上)
  9. c#和java工资相差多少岁_为什么C#程序员平均工资水平比Java程序员低?
  10. 计算机专业同学综合自我评估,计算机专业学生个人自我评价
  11. UE4 合并静态网格体
  12. PHP替换指定字符 阿星小栈
  13. 20多岁的年纪,做什么将来才不后悔?
  14. win7c盘空间越来越小_你Windows10的C盘究竟多大才合适
  15. 华三路由器配置mstp多生成树协议
  16. 英语词汇 talk down to 的中英翻译解释和例子
  17. css加空格的方法,css如何加空格
  18. 基于C#实现的在线聊天室的桌面系统软件
  19. 线性代数笔记17——正交向量与正交子空间
  20. 微信小程序可自定义单片机温湿度阈值(基于esp32c3+onenet+微信小程序)

热门文章

  1. 听大佬学长RQY报告有感
  2. 自定义eachFile遍历文件夹文件
  3. Atitit.跨语言 java c#.net php js常用的codec encode算法api 兼容性  应该内置到语言里面...
  4. html图片上下翻滚展示代码
  5. 包头昆区多大面积_两套楼房,放了整整19车垃圾!包头这对母女的“特殊癖好”,让邻居彻底不能忍了.........
  6. 在DataGridView控件中加入ComboBox下拉列表框的实现
  7. 美国计算机科学厉害的大学,求推荐美国综合排名40~70间计算机科学较好的大学...
  8. 以太网的MAC帧(二)
  9. Reverse Integer
  10. shared_ptr循环引用定置删除器