线程池与并行度

展示线程池如何工作于大量的异步操作,以及它与创建大量单独的线程的方式有什么不同。

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

执行完成

*/

 

posted @ 2016-08-15 18:41  茗::流  阅读(197)  评论(0)    收藏  举报
如有雷同,纯属参考。如有侵犯你的版权,请联系我。