什么是线程池(Pool)?
水池装水,线程池装线程。池(Pool)是一个很常见的提高性能的方式,之所以有这些池是因为线程和数据库连接的创建和关闭是一种比较昂贵的行为。对于这种昂贵的资源我们往往会考虑在一个池容器中放置一些资源,在用的时候去拿,在不够的时候添点,在用完就归还,这样就可以避免不断的创建资源和销毁资源。
最大线程(MaxThreads)?
池中能容纳的最大线程数,就好比一个5L的水桶,硬是要装10L的水肯定是装不下的,线程池也一样,可以使用SetMaxThreads来设置最大线程,如果不设置,系统会根据当前计算机的配置来计算默认最大线程。
最小线程(MinThreads)?
之所以使用线程池是不希望线程在创建后运行结束后理解回收,这样的话以后要用的时候还需要创建,我们可以让线程池至少保留几个线程,即使没有线程在工作也保留。
简单示例:
首先,我们设置线程池最大线程是 300 个,最小线程是100个。
然后,我们需要有500个线程需要创建,每个线程执行需要10秒、
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
namespace ConsoleApplication39
{
class Program
{
static void Main(string[] args)
{
int workerThreads, completionPortThreads;
//设置线程池中最大线程为300个
ThreadPool.SetMaxThreads(300, 300);
//线程池空闲线程100个,即没有线程在工作线程池中也要保留100个线程
ThreadPool.SetMinThreads(100, 100);
ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
//输出:线程池中最大工作线程300个,IO线程300个
Console.WriteLine("线程池中最大工作线程{0}个,IO线程{1}个\n", workerThreads, completionPortThreads);
//声明一个线程回调的委托
WaitCallback callback = ExecuteMethod;
//申请10个线程执行
for (int i = 0; i < 500; i++)
{
//如果线程池中有线程,就执行回调方法
ThreadPool.QueueUserWorkItem(callback);
Thread.Sleep(10);
}
Console.ReadLine();
}
private static int i = 1;
public static void ExecuteMethod(object state)
{
Console.WriteLine("第{0}个工作线程正在运行\n", i);
i++;
//每个线程执行5秒
Thread.Sleep(10000);
}
}
}
运行效果可以看出来,前100个线程很快就能申请成功并执行.
而后,线程池最小100个空闲线程已经使用完了之后,线程池需要创建新的线程,这个线程申请的时间视.net framework而定,默认大概半秒钟。(这里执行明显就慢了许多)
10秒之后,最初的100个线程已经运行完了,将会还给线程池,此时池中又有100个空闲线程可以使用了。(这里执行又快了)