C# 线程池 ThreadPool
1. 线程池整体概括:
创建线程还是比较简单的,但是由于线程的创建和销毁需要耗费一定的开销(默认情况下,主线程占用1M,子线程占用512KB,线程越多,占用内存也越多),过多的使用线程反而会造成内存资源的浪费,从而影响性能,出于对性能的考虑,于是引入了线程池的概念。
线程池并不是在CLR初始化的时候立刻创建的,而是在应用程序要创建线程来执行任务的时候,线程池才会初始化一个线程,初始化的线程和其他线程一样,但是在线程完成任务之后不会自行销毁,而是以挂起的状态回到线程池,当应用程序再次向线程池发出请求的时候,线程池里挂起的线程会再度激活执行任务。这样做可以减少线程创建和销毁所带来的开销。
简单说:线程池,其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。线程池非常适合大量小的运算。当应用程序想要执行一个异步操作时,需要调用QueueUserWorkItem方法将对应的任务添加到线程池中。线程池会从队列中提取任务, 并且将其委派给线程池中的线程执行。
使用线程池的方法:
ThreadPool.QueueUserWorkItem(CallBackWorkItem); //CallBackWorkItem 参数为线程池线程执行的回调方法
ThreadPool.QueueUserWorkItem(CallBackWorkItem, "abc"); //CallBackWorkItem 参数为线程池线程执行的回调方法 第二个参数表示传递给回调方法的参数void CallBackWorkItem(object state)
{Console.WriteLine("子线程执行");if(state != null){Console.WriteLine("使用这行语句调用了这个线程方法 : ThreadPool.QueueUserWorkItem(CallBackWorkItem, "abc")"); }else{Console.WriteLine("使用这行语句调用了这个线程方法 : ThreadPool.QueueUserWorkItem(CallBackWorkItem)"); }
}
2. 线程池使用后性能提升例子:
测试下通过创建线程与利用线程池线程来做事所需时间及观察下利用线程池时是不是只用到少数几个线程。
static void Main(string[] args)
{Stopwatch sw = new Stopwatch();sw.Start();for (int i = 0; i < 1000; i++){Thread thread = new Thread(() => {int count = 0;count++;});thread.Start();//new Thread(() =>//{// int count = 0;// count++;//}).Start(); }sw.Stop();Console.WriteLine("运行创建线程所花费时间"+sw.ElapsedMilliseconds);sw.Restart();//重置下计时器for (int i = 0; i < 1000; i++){//此处s为WaitCallback类型,转到定义查看为public delegate void WaitCallback(object state),即是有一个参数的无返回值的委托ThreadPool.QueueUserWorkItem((s) =>{int count = 0;Console.WriteLine(Thread.CurrentThread.ManagedThreadId);count++;});}sw.Stop();Console.WriteLine("运行线程池线程所花费时间"+sw.ElapsedMilliseconds);Console.ReadKey();
}
运行结果的部分截图如下:
可以看到通过创建线程循环的输出远远大于利用线程池里线程循环输出所需时间,线程池的效率很高,同时利用线程池的循环只用到了少数几个线程。
3. 深入理解线程池的例子:
class Program
{static void Main(string[] args){ThreadDemoClass demoClass = new ThreadDemoClass();//实例化类的对象//使用委托绑定线程池要执行的方法(无参数)WaitCallback waitCallback1 = demoClass.Run1;//将方法排入队列,在线程池变为可用时执行ThreadPool.QueueUserWorkItem(waitCallback1);//使用委托绑定线程池要执行的方法(有参数)WaitCallback waitCallback2 = new WaitCallback(demoClass.Run1);//将方法排入队列,在线程池变为可用时执行ThreadPool.QueueUserWorkItem(waitCallback2, "张三");UserInfo userInfo = new UserInfo();userInfo.Name = "李四";userInfo.Age = 33;//使用委托绑定线程池要执行的方法(有参数,自定义类型的参数)WaitCallback waitCallback3 = new WaitCallback(demoClass.Run2);//将方法排入队列,在线程池变为可用时执行ThreadPool.QueueUserWorkItem(waitCallback3, userInfo);Console.WriteLine();Console.WriteLine("Main thread working...");Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());Console.ReadKey();}
}
public class ThreadDemoClass
{public void Run1(object obj){string name = obj as string;Console.WriteLine();Console.WriteLine("Child thread working...");Console.WriteLine("My name is " + name);Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());}public void Run2(object obj){UserInfo userInfo = (UserInfo)obj;Console.WriteLine();Console.WriteLine("Child thread working...");Console.WriteLine("My name is " + userInfo.Name);Console.WriteLine("I'm " + userInfo.Age + " years old this year");Console.WriteLine("Child thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());}
}public class UserInfo
{public string Name { get; set; }public int Age { get; set; }
}
运行结果:
本文根据徐照兴教授讲义编写,有些改动。
C# 线程池 ThreadPool相关推荐
- C#.Net使用线程池(ThreadPool)与专用线程(Thread)
线程池(ThreadPool)使用起来很简单,但它有一些限制: 1. 线程池中所有线程都是后台线程,如果进程的所有前台线程都结束了,所有的后台线程就会停止.不能把入池的线程改为前台线 程. 2. 不能 ...
- C# 线程池ThreadPool
什么是线程池?为什么要用线程池?怎么用线程池? 1. 什么是线程池? .NET Framework的ThreadPool类提供一个线程池,该线程池可用于执行任务.发送工作项.处理异步 I/O.代表其他 ...
- 手撕线程池 ThreadPool
为了更加方便理解线程池 我们都知道线程池和任务就好比生产者消费者之间的关系也就是如图! 先分析:我们可以将线程池中的线程看作消费者,可以将main(只是方便测试)看作生产者 总体思路: 实现一个阻塞队 ...
- threadpool的数量_多线程之旅(11)_如何限制系统线程池ThreadPool的最大最小并发数量_SetMaxThreads/SetMinThreads用法...
ThreadPool有两个设置线程池并发数量的方法,分别是: ThreadPool.SetMinThreads(int workerThreads, int completionPortThreads ...
- 线程池(ThreadPool)
线程池ThreadPool 1.线程池简介 2.线程池参数说明(重点) 2.1 常用参数说明 2.2 拒绝策略(重点) 3.线程池底层工作原理 4.入门案例 1.线程池简介 线程池(英语:thre ...
- Java线程池ThreadPool详解
Java线程池ThreadPool详解 1. 线程池概述 1.1 线程池简介 1.2 线程池特点 1.3 线程池解决问题 2. 线程池原理分析 2.1 线程池总体设计 2.6 线程池流转状态 2.2 ...
- 线程池ThreadPool知识碎片和使用经验速记
ThreadPool(线程池)大概的工作原理是,初始时线程池中创建了一些线程,当应用程序需要使用线程池中的线程进行工作,线程池将会分配一个线程,之后到来的请求,线程池都会尽量使用池中已有的这个线程进行 ...
- C# 多线程 线程池(ThreadPool) 2 如何控制线程池?
线程池启动了,但是没有方法去控制线程池,如果子线程出现了问题,难道线程池就死了吗? 我们可以设置线程池的线程数量,进行加入任务,线程池会自动分配并且合理的执行,但是控制不了又有啥意思呢. 线程池里线程 ...
- 简单使用Boost线程池threadpool
场景: 1.在一些多线程的程序中,比如服务端响应请求时,可以同时响应多个客户端的请求,但是响应请求的个数(即线程)的个数过多的话就会造成系统资源损耗过多而宕机,还比在做一些下载的程序时,可同时开5个下 ...
- 线程池ThreadPool,线程池底层ThreadPoolExecutor方法七大参数,拒绝策略,以及实际开发中高并发下用到哪个线程池?
为什么要用线程池 基本的三个线程池的底层就是ThreadPoolExecutor类 ExecutorService threadPool = Executors.newFixedThreadPool( ...
最新文章
- php memcache 封装类,PHP 自定义session储存 MEMCACHE 方式类
- 牛B人才简历中的一段
- 转:inux shell脚本的字符串截取
- Android 起调系统功能,打开系统浏览器,拨打电话,发送短信,手机震动,跳转到设置通知开关页面
- 算法讲解 -- 区间dp经典模型与优化(石子归并)
- JavaScript中Object.keys、Object.getOwnPropertyNames区别
- Java 输出指定目录下的所有文件
- 苹果CMSv10官方版程序包
- CSS 实现DIV浮动定位不闪
- python 人脸识别调整人脸大的距离_Python 人脸识别就多简单,看这个就够了!
- JSONTools Validator的使用
- 计算机打印字与印刷字的大小,[转载]实际大小、实际印刷大小 字号 磅数 尺寸对照表及图片...
- 计算机学院实验室安全管理办法,计算机科学学院实验室安全管理制度
- 用大数据调控旅游市场
- python爬取奇书网小说
- 好一个“Exchange20003”
- 未能从dhcp服务器获得ip地址,当出现无法从DHCP服务器中获得地址的常见处理步骤...
- 大屏antdesign走马灯轮播加图形渲染
- Java游戏项目之坦克大战
- 北京汉正天成科技有限公司大家听说过没?这家公司怎么样?