C# ThreadPool类(线程池)
地址: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线程的最大线程数。
- ThreadPool.GetMax(out in workerThreads,out int completionPortThreads);
- 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类(线程池)相关推荐
- 线程池ThreadPool,线程池底层ThreadPoolExecutor方法七大参数,拒绝策略,以及实际开发中高并发下用到哪个线程池?
为什么要用线程池 基本的三个线程池的底层就是ThreadPoolExecutor类 ExecutorService threadPool = Executors.newFixedThreadPool( ...
- Android通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比
在加载大量数据的时候,经常会用到异步加载,所谓异步加载,就是把耗时的工作放到子线程里执行,当数据加载完毕的时候再到主线程进行UI刷新.在数据量非常大的情况下,我们通常会使用两种技术来进行异步加载,一是 ...
- Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比
Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比 标签: AndroidAsyncTaskThreadPool异步加载view 2 ...
- ScheduledThreadPool 源码解析——定时类线程池是如何工作的
文章目录 引言 一.ScheduledThreadPool 使用示例 1. 延时类的定时任务 `schedule` 2. 延时类,固定周期执行任务 `scheduleAtFixedRate` 3. 延 ...
- c# ThreadPool.QueueUserWorkItem线程池的应用
示例,将数据分批 ,每次1000条放入线程池中执行 dt 是查询出来的DataTable 数据. public List<AtmTaskLogdetail> OrderKPI_New(Da ...
- 9,线程池 threadPool 与 线程池执行器 threadPoolExecutor
待续 转载于:https://www.cnblogs.com/zyguo/p/4346378.html
- Android多线程:这是一份全面 详细的线程池(ThreadPool)讲解教程
前言 对于多线程,大家应该很熟悉.但是,大家了解线程池吗? 今天,我将带大家全部学习关于线程池的所有知识. 目录 1. 简介 2. 工作原理 2.1 核心参数 线程池中有6个核心参数,具体如下 上述6 ...
- 线程池ThreadPool知识碎片和使用经验速记
ThreadPool(线程池)大概的工作原理是,初始时线程池中创建了一些线程,当应用程序需要使用线程池中的线程进行工作,线程池将会分配一个线程,之后到来的请求,线程池都会尽量使用池中已有的这个线程进行 ...
- ThreadPool 线程池
文章目录 ThreadPool 线程池 游泳池 线程池简介(三大方法,七大参数,四大策略) Executor类 线程池参数说明 拒绝策略(重点) Executors 线程池的方法与创建 newCach ...
最新文章
- 用AI加速物联网落地,安富利的客户洞察和解决之道
- array initization in matlab zeros(1000)
- citrix协议ICA技术原理
- Android RecyclerView封装下拉刷新与上拉加载更多
- 如何导出项目到本地_如何在win10中导入/导出组策略设置,这个技巧很实用
- 搭建redis主从结构
- OpenJDK 14 与 OpenJDK 8 及多个主要版本的性能基准测试对比
- [转][darkbaby]任天堂传——失落的泰坦王朝(上)
- c#和java工资相差多少岁_为什么C#程序员平均工资水平比Java程序员低?
- 计算机专业同学综合自我评估,计算机专业学生个人自我评价
- UE4 合并静态网格体
- PHP替换指定字符 阿星小栈
- 20多岁的年纪,做什么将来才不后悔?
- win7c盘空间越来越小_你Windows10的C盘究竟多大才合适
- 华三路由器配置mstp多生成树协议
- 英语词汇 talk down to 的中英翻译解释和例子
- css加空格的方法,css如何加空格
- 基于C#实现的在线聊天室的桌面系统软件
- 线性代数笔记17——正交向量与正交子空间
- 微信小程序可自定义单片机温湿度阈值(基于esp32c3+onenet+微信小程序)
热门文章
- 听大佬学长RQY报告有感
- 自定义eachFile遍历文件夹文件
- Atitit.跨语言 java c#.net php js常用的codec encode算法api 兼容性 应该内置到语言里面...
- html图片上下翻滚展示代码
- 包头昆区多大面积_两套楼房,放了整整19车垃圾!包头这对母女的“特殊癖好”,让邻居彻底不能忍了.........
- 在DataGridView控件中加入ComboBox下拉列表框的实现
- 美国计算机科学厉害的大学,求推荐美国综合排名40~70间计算机科学较好的大学...
- 以太网的MAC帧(二)
- Reverse Integer
- shared_ptr循环引用定置删除器