• 线程池与并行度


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

    大量创建线程(消耗内存、CPU系统资源,请观察)

    使用线程池:执行的时间更长,但对系统资源消耗要小的多

    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))//这里给CountdownEvent指定计数为500
                {
                    for (int i = 0; i < count; i++)
                    {
                        //使用普通线程
                        var t1 = new Thread(() =>
                        {
                            //CurrentThreadInfo("UseThreads()的");
    
                            Thread.Sleep(TimeSpan.FromMilliseconds(100));
                            countdown.Signal();//每次循环CountdownEvent在这里计数减1,一直减少到0
                        });
                        t1.Start();
                    }
    
                    countdown.Wait();//主线程一开始在这里停止并等待,CountdownEvent计数减少到0的时候,这里主线程开始执行
                }
            }
    
            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:		{1}", name, Thread.CurrentThread.ManagedThreadId));
                builder.AppendLine(String.Format("{0}是否使用线程池:	{1}", name, Thread.CurrentThread.IsThreadPoolThread));
                builder.AppendLine(String.Format("{0}是否后台线程:	{1}", name, Thread.CurrentThread.IsBackground));
                builder.AppendLine(String.Format("{0}线程状态:		{1}", name, Thread.CurrentThread.ThreadState.ToString()));
                builder.AppendLine(String.Format("{0}当前时间:		{1}", name, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
                builder.AppendLine("");
    
                Console.WriteLine(builder.ToString());
            }
        }
    }

    工作原理:

    使用普通线程

    当主程序启动时,创建了很多不同的线程,每个线程都运行一个操作。该操作打印出线程ID并阻塞线程100毫秒。结果我们创建了500个线程,全部并行运行这些操作。虽然在我的机器上的总耗时是300毫秒,但是所有线程消耗了大量的操作系统资源

    使用线程池

    然后我们使用了执行同样的任务,只不过部位每个操作创建一个线程,儿将他们放入到线程池中。然后线程池开始执行这些操作。线程池在快结束时创建更多的线程,但是仍然花费了更多的时间,在我机器上是12秒。我们为操作系统节省了内存和线程数,但是为此付出了更长的执行时间。

  • 相关阅读:
    uniapp中的跳转传参
    图解排序算法(三)之堆排序
    serverlesss
    kvm
    用户态和内核态的理解和区别
    MySQL优化十大技巧
    不懂数据库索引的底层原理?那是因为你心里没点b树
    让你的 Linux 命令骚起来
    史上最简约的vi教程
    mysql 四种隔离级别
  • 原文地址:https://www.cnblogs.com/gougou1981/p/12443839.html
Copyright © 2020-2023  润新知