1.在多线程中线程池可以减少我们创建线程,并合理的复用线程池中的线程。因为在线程池中有线程的线程处于等待分配任务状态。
2.不必管理和维护生存周期短暂的线程,不用在创建时为其分配资源,在其执行完任务之后释放资源。
3.线程池会根据当前系统特点对池内的线程进行优化处理。
我们把任务交给线程池去完成后,无法控制线程的优先级,设置线程的一些名称等信息。[不过我们可以在放入线程池之前加一层来完善这些工作]
示例代码:
int workerThreads, completionPortThreads; ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads); Console.WriteLine("线程池中辅助线程的最大数目:{0}.线程池中异步 I/O 线程的最大数目:{1}", workerThreads, completionPortThreads); ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads); Console.WriteLine("线程池根据需要创建的最少数量的辅助线程:{0}.线程池根据需要创建的最少数量的异步 I/O 线程:{1}", workerThreads, completionPortThreads); //设置线程池默认参数 ThreadPool.SetMaxThreads(100, 100); ThreadPool.SetMinThreads(2, 2); ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads); Console.WriteLine("线程池中辅助线程的最大数目:{0}.线程池中异步 I/O 线程的最大数目:{1}", workerThreads, completionPortThreads); ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads); Console.WriteLine("线程池根据需要创建的最少数量的辅助线程:{0}.线程池根据需要创建的最少数量的异步 I/O 线程:{1}", workerThreads, completionPortThreads); ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads); Console.WriteLine("可用辅助线程的数目:{0}.可用异步 I/O 线程的数目:{1}", workerThreads, completionPortThreads);
输出结果:
1.CLR线程池最大数:1023。I/O线程池最大数:1000。
2.线程池中最大数目和最少数量我们都可以修改。
[msdn建议:不能将辅助线程的数目或 I/O 完成线程的数目设置为小于计算机的处理器数目。
如果承载了公共语言运行时,例如由 Internet 信息服务 (IIS) 或 SQL Server 承载,主机可能会限制或禁止更改线程池大小。
更改线程池中的最大线程数时需谨慎。 虽然这类更改可能对您的代码有益,但对您使用的代码库可能会有不利的影响。
将线程池大小设置得太大可能导致性能问题。 如果同时执行的线程太多,任务切换开销就成为影响性能的一个主要因素。]
线程池的常用方法:
public static bool QueueUserWorkItem(WaitCallback callBack, object state);
WaitCallback:表示线程池线程要执行的回调方法。
[ComVisible(true)] public delegate void WaitCallback(object state);
示例代码:
ThreadPool.SetMaxThreads(12, 12); int workerThreads, completionPortThreads; ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads); Console.WriteLine("线程池中辅助线程的最大数目:{0}.线程池中异步 I/O 线程的最大数目:{1}", workerThreads, completionPortThreads); ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads); Console.WriteLine("线程池根据需要创建的最少数量的辅助线程:{0}.线程池根据需要创建的最少数量的异步 I/O 线程:{1}", workerThreads, completionPortThreads); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); WaitCallback callback = index => { Console.WriteLine(String.Format("{0}: Task {1} started", stopwatch.Elapsed, index)); Thread.Sleep(10000); Console.WriteLine(String.Format("{0}: Task {1} finished", stopwatch.Elapsed, index)); }; for (int i = 0; i < 20; i++) { ThreadPool.QueueUserWorkItem(callback, i); } Console.Read();
输出结果:
1 00:00:00.0009109: Task 0 started 2 00:00:00.0011152: Task 2 started 3 00:00:00.0010331: Task 1 started 4 00:00:00.0013977: Task 3 started 5 00:00:01.0640656: Task 4 started 6 00:00:01.5959091: Task 5 started 7 00:00:02.1282115: Task 6 started 8 00:00:02.6604640: Task 7 started 9 00:00:03.1919942: Task 8 started 10 00:00:03.7241812: Task 9 started 11 00:00:04.2562930: Task 10 started 12 00:00:04.7883300: Task 11 started 13 00:00:10.0337174: Task 0 finished 14 00:00:10.0337912: Task 2 finished 15 00:00:10.0341861: Task 3 finished 16 00:00:10.0343205: Task 13 started 17 00:00:10.0342149: Task 12 started 18 00:00:10.0345326: Task 1 finished 19 00:00:10.0347520: Task 14 started 20 00:00:10.9400517: Task 15 started 21 00:00:11.0639205: Task 4 finished 22 00:00:11.0643085: Task 16 started 23 00:00:11.5960161: Task 5 finished 24 00:00:11.5966256: Task 17 started 25 00:00:12.1279212: Task 6 finished 26 00:00:12.1294851: Task 18 started 27 00:00:12.6609840: Task 7 finished 28 00:00:12.6613285: Task 19 started 29 00:00:13.1921462: Task 8 finished 30 00:00:13.7240561: Task 9 finished 31 00:00:14.2560682: Task 10 finished 32 00:00:14.7880441: Task 11 finished 33 00:00:20.0342193: Task 13 finished 34 00:00:20.0354372: Task 14 finished 35 00:00:20.0343117: Task 12 finished 36 00:00:20.9402809: Task 15 finished 37 00:00:21.0662233: Task 16 finished 38 00:00:21.5983967: Task 17 finished 39 00:00:22.1293673: Task 18 finished 40 00:00:22.6623133: Task 19 finished
1:00秒共开启4个线程(为线程池中最少线程数:当达到线程池中创建线程最小线程时,线程池开始创建线程)。
2:01到04秒之间平均1秒创建一个线程.线程池创建线程每秒不会超过2个。
3:04秒时线程池中的线程数已达最大值,无法在创建新的线程。
4:10秒时线程池中线程ID0-4已完成任务,线程池又开始重新创建线程(线程ID为:12-15)共4个。
示例代码:
ThreadPool.SetMaxThreads(5, 5); ThreadPool.SetMinThreads(5, 5); int workerThreads, completionPortThreads; ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads); Console.WriteLine("线程池中辅助线程的最大数目:{0}.线程池中异步 I/O 线程的最大数目:{1}", workerThreads, completionPortThreads); ManualResetEvent waitHandle = new ManualResetEvent(false); Stopwatch watch = new Stopwatch(); watch.Start(); //IO线程池 WebRequest request = HttpWebRequest.Create("http://www.taobao.com/"); request.BeginGetResponse(ar => { var response = request.EndGetResponse(ar); Console.WriteLine(watch.Elapsed + ": Response Get"); }, null); //CLR线程池 for (int i = 0; i < 10; i++) { ThreadPool.QueueUserWorkItem(index => { Console.WriteLine(String.Format("{0}: Task {1} started", watch.Elapsed, index)); waitHandle.WaitOne(); //阻塞线程池 },i); } Console.Read();
输出结果:
1. 把CLR线程池最大线程数和IO线程池最大线程数都设置为:5.
2.向CLR线程池中增加10个线程任务,并且阻塞线程池。最后输出结果中只打印出5个线程运行的信息。CLR线程池已达最大线程数,IO线程依然有回复数据。
证明CLR线程池占满后不会影响到IO线程池的使用。