1、為什么需要使用線程池(Thread Pool)
- 減少線程間上下文切換。線程執行一定的時間片后,系統會自動把cpu切換給另一個線程使用,這時還需要保存當前的線程上下文狀態,並加載新線程的上下文狀態。當程序中有大量的線程時,每個線程分得的時間片會越來越少,可能會出現線程未處理多少操作,就需要切換到另一線程,這樣頻繁的線程間上下文切換會花費大量的cpu時間。
- 減少內存占用。系統每創建一條物理線程,需要大概花費1MB的內存空間,許多程序喜歡先創建多條物理線程,並周期輪詢來處理各自的任務,這樣既消耗了線程上下文切換的時間,還浪費了內存。這些任務可能只需要一條線程就能滿足要求。假如某一任務需要執行較長的周期,線程池還可以自動增加線程,並在空閑時,銷毀線程,釋放占用的內存。
2、為什么不使用.Net默認的線程池
- .Net默認的線程池(ThreadPool)是一個靜態類,所以是沒辦法自己創建一個新的程序池的。默認的線程池與應用程序域(AppDomain)掛鈎,一個AppDomain只有一個線程池。假如在線程池中執行了一個周期較長的任務,一直占用着其中一個線程,可能就會影響到應用程序域中的其他程序的性能。例如,假如在Asp.Net的線程池中執行一個周期較長的任務,就會影響請求的並發處理能力(線程池默認有個最大線程數)。 3、SmartThreadPool特性和優點
SmartThreadPool特性如下:
- 池中的線程數量會根據負載自動增減
- 任務異步執行后可以返回值
- 處於任務隊列中未執行的任務可以取消
- 回調函數可以等待多個任務都執行完成后再觸發
- 任務可以有優先級(priority)
- 任務可以分組
- 支持泛型Action<T> 和 Func<T>
- 有性能監測機制
4、使用示例 最簡單的使用方法:
// 創建一個線程池 SmartThreadPool smartThreadPool = new SmartThreadPool(); // 執行任務 smartThreadPool.QueueWorkItem(() => { Console.WriteLine("Hello World!"); });
帶返回值的任務:
// 創建一個線程池 SmartThreadPool smartThreadPool = new SmartThreadPool(); // 執行任務 var result = smartThreadPool.QueueWorkItem(() => { var sum = 0; for (var i = 0; i < 10; i++) sum += i; return sum; }); // 輸出計算結果 Console.WriteLine(result.Result);
等待多個任務執行完成:
// 創建一個線程池 SmartThreadPool smartThreadPool = new SmartThreadPool(); // 執行任務 var result1 = smartThreadPool.QueueWorkItem(() => { //模擬計算較長時間 Thread.Sleep(5000); return 3; }); var result2 = smartThreadPool.QueueWorkItem(() => { //模擬計算較長時間 Thread.Sleep(3000); return 5; }); bool success = SmartThreadPool.WaitAll( new IWorkItemResult[] { result1, result2 }); if (success) { // 輸出結果 Console.WriteLine(result1.Result); Console.WriteLine(result2.Result); }
5、結論 使用SmartThreadPool可以簡單就實現支持多線程的程序,由線程池來管理線程,可以減少死鎖的出現。SmartThreadPool還支持簡單的生產者-消費者模式,當不需要對任務進行持久化時,還是很好用的。 6、擴展閱讀 http://www.codeproject.com/KB/threads/smartthreadpool.aspx http://smartthreadpool.codeplex.com/ http://www.albahari.com/threading/