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秒共開啟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線程池的使用。