多线程(3)ThreadPool
2018-06-17 19:07:16来源:未知 阅读 ()
使用Thread类已经可以创建并启动线程了,但是随着开启的线程越来越多,线程的创建和终止都需要手动操作,非常繁琐,另一个问题是,开启更多新的线程但是没有用的线程没有及时得到终止的时候,会占用越来越多的系统资源,影响性能。
所以,.net为我们引入了ThreadPool(线程池),我们只需要把要执行的任务放到线程池中即可,线程的开启包括资源的释放都由线程池帮我们完成。下面看一下怎么使用线程池。
线程池ThreadPool
核心类:System.Threading.ThreadPool, 线程池受.Net CLR管理的,每一个CLR都有一个线程池实例。
每个进程都有一个线程池,线程池的默认大小为:每个可用的处理器有 25 个线程。使用 SetMaxThreads 方法可以更改线程池中的线程数。每个线程使用默认的堆栈大小并按照默认的优先级运行。
ThreadPool类型拥有一个QueueUserWorkItem的静态方法。该静态方法接收一个委托,代表用户自定义的一个异步操作。在改方法被调用后,委托会进入到内部队列中。如果线程池中没有任何线程,将创建一个新的工作者线程(worker thread)并将队列中的第一个委托放入到该工作者线程中。
如果向线程池中放入新的操作,当之前的所有操作完成后,很可能只需重用一个线程来执行这些新的操作。如果QueueUserWorkItem执行的频率过快,线程池将创建更多的线程来执行这些新放入的异步委托。
线程池中的线程数是有限的,如果没有空闲的线程来执行这些异步委托操作,这种情况下,新的异步委托操作将在线程池的内部队列中等待,直到线程池中年的工作者线程空闲(有能力)来执行。
当停止向线程池中放入新的异步委托操作时,线程池会删除一定事件后过期的不在使用的线程,同时释放不再使用的系统资源。
线程池的使用非常简单,如下代码:
namespace ConsoleApplication18 { class Program { static void Main(string[] args) { Console.WriteLine("Main thread starting..."); //1,不带参数 ThreadPool.QueueUserWorkItem(AsyncAction); Thread.Sleep(TimeSpan.FromMilliseconds(3000)); //2,带参数 ThreadPool.QueueUserWorkItem(AsyncAction, "Async state"); Thread.Sleep(TimeSpan.FromMilliseconds(3000)); //3,lambda表达式 ThreadPool.QueueUserWorkItem(item => { Console.WriteLine("Sub thread starting..."); Console.WriteLine("Action state:" + item ?? string.Empty); Console.WriteLine(string.Format("Current thread id:{0}", Thread.CurrentThread.ManagedThreadId)); }, "Lambda state"); Thread.Sleep(TimeSpan.FromMilliseconds(3000)); Console.WriteLine("Main thread completed!"); Console.ReadKey(); } /// <summary> /// 委托匹配方法 /// </summary> /// <param name="obj"></param> static void AsyncAction(Object obj) { Console.WriteLine("Sub thread starting..."); Console.WriteLine("Action state:" + obj ?? string.Empty); Console.WriteLine(string.Format("Current thread id:{0}", Thread.CurrentThread.ManagedThreadId)); } } }
输出结果:
不适合使用线程池的场景
使用线程池创建线程这么简单,然后性能又好,是不是以后创建线程都去使用线程池呢?答案是否定的。
那么,以下场景是不适合使用线程池,而是自己创建并管理线程:
- 需要前台线程时。因为线程池默认创建的都是后台线程。
- 需要线程具有特定的优先级。因为放到线程池中的线程都是由线程池来调度的,无法对其优先级进行设置。
- 需要长时间运行的任务。由于线程池具有最大线程数限制,因此大量阻塞的线程池线程可能会阻止任务启动。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:简单抓取小程序大全,并展示。
下一篇:面向对象思想----不看后悔!
- Delphi10.3下自带系统托盘 TrayIcon的使用 2020-06-01
- delphi10.3安装使用mySQL 2020-05-31
- QF中间件 2020-02-04
- 人脸识别Demo 2019-08-29
- delphi使用Chilkat 组件和库从SFTP下载文件 2019-08-26
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash