地址:https://www.cnblogs.com/scmail81/archive/2018/08/19/9503266.htmlhtml
CLR线程池并不会在CLR初始化时当即创建线程,而是在应用程序要建立线程来运行任务时,线程池才初始化一个线程。
线程池初始化时是没有线程的,线程池里的线程的初始化与其余线程同样,可是在完成任务之后,该线程不会自行销毁,而是以挂起的状态返回到线程池。直到应用程序再次向线程池发出请求时,线程池里挂起的线程就会再度激活执行任务。
这样既节省了创建线程所形成的性能损耗,也可让多个任务反复重用同一线程,从而在应用程序生存期内节约大量开销。网络
经过CLR线程池所创建的线程老是默认为后台线程,优先级数为ThreadPriority.Normal。ide
CLR线程池分为工做者线程(workerThreads)与I/O线程(completionPortThreads)两种:函数
线程池的最大值通常默认为1000、2000。当大于此数目的请求时,将保持排队状态,直到线程池里有线程可用。性能
使用CLR线程池的工做者线程通常有两种方式:测试
要注意,不管是经过ThreadPool.QueueUserWorkItem()仍是委托,调用的都是线程池里的线程。优化
经过如下两个方法能够读取和设置CLR线程池中工做者线程与I/O线程的最大线程数。spa
若想测试线程池中有多少线程正在投入使用,能够经过ThreadPool.GetAvailableThreads(out in workThreads,out int conoletionPortThreads)方法。操作系统
方法 | 说明 |
GetAvailableThreads | 剩余空闲线程数 |
GetMaxThreads | 最多可用线程数,全部大于此数目的请求将保持排队状态,直到线程池线程变为可用 |
GetMinThreads | 检索线程池在新请求预测中维护的空闲线程数 |
QueueUserWorkItem | 启动线程池里得一个线程(队列的方式,如线程池暂时没空闲线程,则进入队列排队) |
SetMaxThreads | 设置线程池中的最大线程数 |
SetMinThreads | 设置线程池最少须要保留的线程数 |
咱们可使用线程池来解决上面的大部分问题,跟使用单个线程相比,使用线程池有以下优势:线程
一、缩短应用程序的响应时间。由于在线程池中有线程的线程处于等待分配任务状态(只要没有超过线程池的最大上限),无需建立线程。
二、没必要管理和维护生存周期短暂的线程,不用在建立时为其分配资源,在其执行完任务以后释放资源。
三、线程池会根据当前系统特色对池内的线程进行优化处理。
总之使用线程池的做用就是减小建立和销毁线程的系统开销。在.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(); } } }