线程池与并行度
展示线程池如何工作于大量的异步操作,以及它与创建大量单独的线程的方式有什么不同。
using System; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Diagnostics; namespace Test { class Program { private static void UseThreads(int count) { //通过CountdownEvent可以在主线程中线程池中的任务运行,主线程要等待线程池中的任务完成之后才能继续 using (var countdown = new CountdownEvent(count)) { for (int i = 0; i < count; i++) { //使用普通线程 var t1 = new Thread(() => { //CurrentThreadInfo("UseThreads()的"); Thread.Sleep(TimeSpan.FromMilliseconds(100)); countdown.Signal(); }); t1.Start(); } countdown.Wait(); } } private static void UseThreadPool(int count) { using (var countdown = new CountdownEvent(count)) { for (int i = 0; i < count; i++) { //使用线程池 ThreadPool.QueueUserWorkItem(_ => { //CurrentThreadInfo("UseThreadPool()的"); Thread.Sleep(TimeSpan.FromMilliseconds(100)); countdown.Signal(); }); } countdown.Wait(); } } /// <summary> /// 向线程池放入异步操作 /// </summary> static void Main() { //CurrentThreadInfo("主线程Main()的"); int count = 500; CodeTimer.Initialize(); int iteration = 2; CodeTimer.Time("UseThreads", iteration, () => { Stopwatch sw = new Stopwatch(); sw.Start(); UseThreads(count); sw.Stop(); Console.WriteLine("使用简单线程耗时:{0} - 计数:{1}", sw.ElapsedMilliseconds, sw.ElapsedTicks); }); CodeTimer.Time("UseThreadPool", iteration, () => { Stopwatch sw2 = new Stopwatch(); sw2.Start(); UseThreadPool(count); sw2.Stop(); Console.WriteLine("使用线程池中耗时:{0} - 计数:{1}", sw2.ElapsedMilliseconds, sw2.ElapsedTicks); }); Console.WriteLine("执行完成"); Console.ReadLine(); } /// <summary> /// 当前线程信息 /// </summary> private static void CurrentThreadInfo(string name) { StringBuilder builder = new StringBuilder(); builder.AppendLine(""); builder.AppendLine(String.Format("{0}线程Id:\t\t{1}", name, Thread.CurrentThread.ManagedThreadId)); builder.AppendLine(String.Format("{0}是否使用线程池:\t{1}", name, Thread.CurrentThread.IsThreadPoolThread)); builder.AppendLine(String.Format("{0}是否后台线程:\t{1}", name, Thread.CurrentThread.IsBackground)); builder.AppendLine(String.Format("{0}线程状态:\t\t{1}", name, Thread.CurrentThread.ThreadState.ToString())); builder.AppendLine(String.Format("{0}当前时间:\t\t{1}", name, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); builder.AppendLine(""); Console.WriteLine(builder.ToString()); } } }
打印运行结果:
/* UseThreads 使用简单线程耗时:2360 - 计数:5519551 使用简单线程耗时:1961 - 计数:4585782 Time Elapsed: 4,329ms CPU Cycles: 3,125,549,863 Gen 0: 0 Gen 1: 0 Gen 2: 0 UseThreadPool 使用线程池中耗时:10168 - 计数:23778890 使用线程池中耗时:6113 - 计数:14297250 Time Elapsed: 16,285ms CPU Cycles: 12,732,867 Gen 0: 0 Gen 1: 0 Gen 2: 0 执行完成 */
工作原理:
当主程序启动时,UseThreads()创建了很多不同的线程,每个线程都运行一个操作。
该操作打印线程信息并阻塞线程100毫秒。
结果我们创建了500个线程,全部并行运行这些操作。
UseThreadPool()使用了执行同样的任务,只不过不为每个操作创建一个线程,而将它们放入到线程池中。
然后线程池开始执行这些操作。
总结:
1、UseThreads()总耗时是4秒多,但是所有线程消耗了大量的操作系统资源。
2、UseThreadPool()线程池在快要结束时创建更多的线程,但是仍然花费了更多的时间。
它为 操作系统节省了内存和线程数,但是为此付出了更长的执行时间。
using System; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Diagnostics; namespace Test { class Program { private static object objLock = new object(); private static void UseThreads(int count) { for (int i = 0; i < count; i++) { lock (objLock) { //使用普通线程 var t1 = new Thread(() => { Thread.Sleep(TimeSpan.FromMilliseconds(100)); }); t1.Start(); } } } private static void UseThreadPool(int count) { for (int i = 0; i < count; i++) { lock (objLock) { //使用线程池 ThreadPool.QueueUserWorkItem(_ => { Thread.Sleep(TimeSpan.FromMilliseconds(100)); }); } } } /// <summary> /// 向线程池放入异步操作 /// </summary> static void Main() { int count = 500; CodeTimer.Initialize(); int iteration = 5; CodeTimer.Time("UseThreads", iteration, () => { Stopwatch sw = new Stopwatch(); sw.Start(); UseThreads(count); sw.Stop(); Console.WriteLine("使用简单线程耗时:{0} - 计数:{1}", sw.ElapsedMilliseconds, sw.ElapsedTicks); }); CodeTimer.Time("UseThreadPool", iteration, () => { Stopwatch sw2 = new Stopwatch(); sw2.Start(); UseThreadPool(count); sw2.Stop(); Console.WriteLine("使用线程池中耗时:{0} - 计数:{1}", sw2.ElapsedMilliseconds, sw2.ElapsedTicks); }); Console.WriteLine("执行完成"); Console.ReadLine(); } } }
/* UseThreads 使用简单线程耗时:1743 - 计数:4077120 使用简单线程耗时:1917 - 计数:4483338 使用简单线程耗时:2422 - 计数:5665134 使用简单线程耗时:2528 - 计数:5912870 使用简单线程耗时:2363 - 计数:5527067 Time Elapsed: 10,983ms CPU Cycles: 5,458,292,606 Gen 0: 1 Gen 1: 1 Gen 2: 1 UseThreadPool 使用线程池中耗时:35 - 计数:82165 使用线程池中耗时:0 - 计数:566 使用线程池中耗时:0 - 计数:168 使用线程池中耗时:0 - 计数:166 使用线程池中耗时:0 - 计数:164 Time Elapsed: 44ms CPU Cycles: 28,404,924 Gen 0: 0 Gen 1: 0 Gen 2: 0 执行完成 */

浙公网安备 33010602011771号