• 关于多线程学习总结(五) 线程池


    必须得说点什么

    今天在介绍线程池之前,我得来说说上上篇随笔。关于线程的优先级,我们知道在C#中可以设置线程的优先级,使重要的作业可以优先执行,但是这个优先级不是一成不变的,也就是说就算你设置一个线程的优先级非常高,但是也有可能在优先级较低的线程后执行。优先级高不代表就得到了绝对的通行证,给一个例子大家看看:

     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             Thread test1 = new Thread(new ThreadStart(myThread1));
     6             test1.Priority = ThreadPriority.Lowest;
     7             Thread test2 = new Thread(new ThreadStart(myThread2));
     8             test2.Priority = ThreadPriority.Highest;
     9             Thread test3 = new Thread(new ThreadStart(myThread3));
    10             test3.Priority = ThreadPriority.Normal;
    11             test1.Start();
    12             test2.Start();
    13             test3.Start();
    14             Console.WriteLine("结束");
    15             Console.ReadKey();
    16         }
    17 
    18         public static void myThread1()
    19         {
    20             Console.WriteLine("我的线程1");
    21         }
    22         public static void myThread2()
    23         {
    24             Thread.Sleep(5000);
    25             Console.WriteLine("我的线程2");
    26         }
    27         public static void myThread3()
    28         {
    29             Thread.Sleep(3000);
    30             Console.WriteLine("我的线程3");
    31         }
    32     }

    在上面的例子中我们为线程1设置了最低优先级,线程2设置最高优先级,线程3设置中等优先级,然后在在后面三个方法中分别调用Sleep()方法,使其阻塞,最终我们得到的结果如下所示:

    结束

    我的线程1

    我的线程3

    我的线程2

    看了这个是不是有点感觉了呢?其实在C#中多线程是个挺怪异的东东,它收到多方面因数的影响,从而导致优先级的执行扑朔迷离,每次执行都可能不同。

    线程池

    其实我看到线程池这个东西,天生就有种恐惧感,总觉得它很神秘,属于深奥的东西,今天小弟还真得探它一探、、、

    关于线程池的概念,其实线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程哦,每个线程池都使用默认的堆栈大小,以默认的优先级执行,并处理多线程单元中。

    而且我们都知道一个应用程序可以包含多个线程,这么多的线程管理起来很费力,于是线程池的出现可以帮我们解决相关问题。但是有几点我们需要知道哦,线程池这个东东哇也有不好的地方,有些地方还真使用它不合适,这点后面道来。

    ThreadPool类

    下面来看看MSDN吧,我发现我越来越爱它了,Wonderful

    ThreadPool的概念:提供一个线程池,该线程池可用于发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。

    关于ThreadPool 它有相关的成员

    以上线程的成员我们可以没事儿玩一哈:

     1 int x, y,m,n;
     2 ThreadPool.GetMaxThreads(out x, out y);  //检索可以同时处于活动状态的线程池请求的数目。所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。 
     3 Console.WriteLine("第一次调用GetMaxThreads" + x + "----" + y);      //x指最大线程数,y指异步IO最大线程数
     4 ThreadPool.GetMinThreads(out m, out n);  //线程池在新请求预测中维护的空闲线程数
     5 Console.WriteLine("第一次调用GetMinThreads"+m + "----" + m);  //m指最小线程数,n指异步IO最小线程数
     6 ThreadPool.SetMaxThreads(100,1000);
     7 ThreadPool.GetMaxThreads(out x, out y);  //检索可以同时处于活动状态的线程池请求的数目。所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。 
     8 Console.WriteLine("第二次调用GetMaxThreads" + x + "----" + y);      //x指最大线程数,y指异步IO最大线程数
     9 Console.WriteLine("结束");
    10 Console.ReadKey();

    其实这些东西蛮有意思的,先看看以上代码执行结果:

    这段代码执行是没有任何问题的,可是我们改两个地方,如下所示:

    1 ThreadPool.SetMaxThreads(100000,1000);
    2 ThreadPool.SetMinThreads(3,1000);

    大家猜执行的结果是啥?呵呵试试就知道了,你猜的结果很可能都错了,当我们设置最小线程数大于1023时我们再调用GetMaxThreads方法,我们会发现无论如何最大线程数都是1023。为什么会这样?我们都知道线程有利也有弊,弊端在这里就有所体现,过多的线程导致线程间调度过度频繁,导致线程执行的时间比调度的时间还短,同时又占据更多的内存,所以在这里线程池不允许。

    结合上面的成员,练习练习,木有错的、、、、

    这个不该出现的结尾

    其实关于线程池这个还有一些其他的知识木有提到,比如AutoResetEvent啦,ThreadPool.RegisterWaitForSingleObject啦,今天由于不可抗拒的原因到此停笔,貌似看到此处的园友一定觉得好坑,不过没关系啦,不掉进去怎么会知道那有个坑呢?你说是吧,呵呵,对不住了、、、

    ------如果你觉得此文对你有所帮助,别忘了点击下右下角的推荐咯,谢谢!------

  • 相关阅读:
    springboot+websocket 归纳收集
    flask-admin 快速打造博客 系列一
    Flask-sqlalchemy 语法总结
    python 小问题收集
    pyenv+virtual 笔记
    flask_admin 笔记七 扩展功能
    Flask_admin 笔记六 modelView的内置方法
    spring boot 项目中 maven打第三方lib包时遇到的问题以及解决方法
    java 字符串压缩长度并解压
    highcharts中放aqi及6要素,再加上气象5要素的图
  • 原文地址:https://www.cnblogs.com/vchenpeng/p/3199500.html
Copyright © 2020-2023  润新知