C# 线程--第三线程池
概述
线程池有那些优点:
1.在多线程中线程池可以减少我们创建线程,并合理的复用线程池中的线程。因为在线程池中有线程的线程处于等待分配任务状态。
2.不必管理和维护生存周期短暂的线程,不用在创建时为其分配资源,在其执行完任务之后释放资源。
3.线程池会根据当前系统特点对池内的线程进行优化处理。
线程池的缺点:
我们把任务交给线程池去完成后,无法控制线程的优先级,设置线程的一些名称等信息。[不过我们可以在放入线程池之前加一层来完善这些工作]
线程池参数设置
示例代码:
int workerThreads, completionPortThreads; ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("线程池中辅助线程的最大数目:{0}.线程池中异步 I/O 线程的最大数目:{1}", workerThreads, completionPortThreads); ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("线程池根据需要创建的最少数量的辅助线程:{0}.线程池根据需要创建的最少数量的异步 I/O 线程:{1}", workerThreads, completionPortThreads); //设置线程池默认参数
ThreadPool.SetMaxThreads(, );
ThreadPool.SetMinThreads(, ); ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("线程池中辅助线程的最大数目:{0}.线程池中异步 I/O 线程的最大数目:{1}", workerThreads, completionPortThreads); ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("线程池根据需要创建的最少数量的辅助线程:{0}.线程池根据需要创建的最少数量的异步 I/O 线程:{1}", workerThreads, completionPortThreads); ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("可用辅助线程的数目:{0}.可用异步 I/O 线程的数目:{1}", workerThreads, completionPortThreads);
输出结果:
1.CLR线程池最大数:1023。I/O线程池最大数:1000。
2.线程池中最大数目和最少数量我们都可以修改。
[msdn建议:不能将辅助线程的数目或 I/O 完成线程的数目设置为小于计算机的处理器数目。
如果承载了公共语言运行时,例如由 Internet 信息服务 (IIS) 或 SQL Server 承载,主机可能会限制或禁止更改线程池大小。
更改线程池中的最大线程数时需谨慎。 虽然这类更改可能对您的代码有益,但对您使用的代码库可能会有不利的影响。
将线程池大小设置得太大可能导致性能问题。 如果同时执行的线程太多,任务切换开销就成为影响性能的一个主要因素。]
线程池的使用
线程池的常用方法:
public static bool QueueUserWorkItem(WaitCallback callBack, object state);
WaitCallback:表示线程池线程要执行的回调方法。
[ComVisible(true)]
public delegate void WaitCallback(object state);
示例代码:
ThreadPool.SetMaxThreads(, ); int workerThreads, completionPortThreads; ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("线程池中辅助线程的最大数目:{0}.线程池中异步 I/O 线程的最大数目:{1}", workerThreads, completionPortThreads); ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("线程池根据需要创建的最少数量的辅助线程:{0}.线程池根据需要创建的最少数量的异步 I/O 线程:{1}", workerThreads, completionPortThreads); Stopwatch stopwatch = new Stopwatch();
stopwatch.Start(); WaitCallback callback = index =>
{
Console.WriteLine(String.Format("{0}: Task {1} started", stopwatch.Elapsed, index));
Thread.Sleep();
Console.WriteLine(String.Format("{0}: Task {1} finished", stopwatch.Elapsed, index));
}; for (int i = ; i < ; i++)
{
ThreadPool.QueueUserWorkItem(callback, i);
}
Console.Read();
输出结果:
::00.0009109: Task started
::00.0011152: Task started
::00.0010331: Task started
::00.0013977: Task started
::01.0640656: Task started
::01.5959091: Task started
::02.1282115: Task started
::02.6604640: Task started
::03.1919942: Task started
::03.7241812: Task started
::04.2562930: Task started
::04.7883300: Task started
::10.0337174: Task finished
::10.0337912: Task finished
::10.0341861: Task finished
::10.0343205: Task started
::10.0342149: Task started
::10.0345326: Task finished
::10.0347520: Task started
::10.9400517: Task started
::11.0639205: Task finished
::11.0643085: Task started
::11.5960161: Task finished
::11.5966256: Task started
::12.1279212: Task finished
::12.1294851: Task started
::12.6609840: Task finished
::12.6613285: Task started
::13.1921462: Task finished
::13.7240561: Task finished
::14.2560682: Task finished
::14.7880441: Task finished
::20.0342193: Task finished
::20.0354372: Task finished
::20.0343117: Task finished
::20.9402809: Task finished
::21.0662233: Task finished
::21.5983967: Task finished
::22.1293673: Task finished
::22.6623133: Task finished
1:00秒共开启4个线程(为线程池中最少线程数:当达到线程池中创建线程最小线程时,线程池开始创建线程)。
2:01到04秒之间平均1秒创建一个线程.线程池创建线程每秒不会超过2个。
3:04秒时线程池中的线程数已达最大值,无法在创建新的线程。
4:10秒时线程池中线程ID0-4已完成任务,线程池又开始重新创建线程(线程ID为:12-15)共4个。
CLR线程池与IO线程池
测试CLR线程池占满后,会不会影响IO线程池的正常使用?
示例代码:
ThreadPool.SetMaxThreads(, );
ThreadPool.SetMinThreads(, ); int workerThreads, completionPortThreads; ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("线程池中辅助线程的最大数目:{0}.线程池中异步 I/O 线程的最大数目:{1}", workerThreads, completionPortThreads); ManualResetEvent waitHandle = new ManualResetEvent(false); Stopwatch watch = new Stopwatch();
watch.Start(); //IO线程池
WebRequest request = HttpWebRequest.Create("http://www.taobao.com/");
request.BeginGetResponse(ar =>
{
var response = request.EndGetResponse(ar);
Console.WriteLine(watch.Elapsed + ": Response Get");
}, null); //CLR线程池
for (int i = ; i < ; i++)
{
ThreadPool.QueueUserWorkItem(index =>
{
Console.WriteLine(String.Format("{0}: Task {1} started", watch.Elapsed, index));
waitHandle.WaitOne(); //阻塞线程池
},i);
} Console.Read();
输出结果:
1. 把CLR线程池最大线程数和IO线程池最大线程数都设置为:5.
2.向CLR线程池中增加10个线程任务,并且阻塞线程池。最后输出结果中只打印出5个线程运行的信息。CLR线程池已达最大线程数,IO线程依然有回复数据。
证明CLR线程池占满后不会影响到IO线程池的使用。
C# 线程--第三线程池的更多相关文章
- linux线程篇 (三) 线程的同步
1 互斥量 pthreat_mutex_t mymutex; //1. 创建 初始化 int pthread_mutex_init(pthread_mutex_t *mutex, const pthr ...
- 线程池 异步I/O线程 <第三篇>
在学习异步之前先来说说异步的好处,例如对于不需要CPU参数的输入输出操作,可以将实际的处理步骤分为以下三步: 启动处理: 实际的处理,此时不需要CPU参数: 任务完成后的处理: 以上步骤如果仅仅使用一 ...
- 转载 线程池 异步I/O线程 <第三篇>
在学习异步之前先来说说异步的好处,例如对于不需要CPU参数的输入输出操作,可以将实际的处理步骤分为以下三步: 启动处理: 实际的处理,此时不需要CPU参数: 任务完成后的处理: 以上步骤如果仅仅使用一 ...
- 转:专题三线程池中的I/O线程
上一篇文章主要介绍了如何利用线程池中的工作者线程来实现多线程,使多个线程可以并发地工作,从而高效率地使用系统资源.在这篇文章中将介绍如何用线程池中的I/O线程来执行I/O操作,希望对大家有所帮助. 目 ...
- 第三十四天- 线程队列、线程池(map/submit/shutdown/回调函数)
1.线程列队 queue队列 :使用import queue,用法与进程Queue一样 class queue.Queue(maxsize=0) # 先进先出: q = queue.Queue(3) ...
- JAVA多线程(三) 线程池和锁的深度化
github演示代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-servic ...
- Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)
Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...
- java线程API学习 线程池ThreadPoolExecutor(转)
线程池ThreadPoolExecutor继承自ExecutorService.是jdk1.5加入的新特性,将提交执行的任务在内部线程池中的可用线程中执行. 构造函数 ThreadPoolExecut ...
- (转)Java结束线程的三种方法
背景:面试过程中问到结束线程的方法和线程池shutdown shutdownnow区别以及底层的实现,当时答的并不好. Java结束线程的三种方法 线程属于一次性消耗品,在执行完run()方法之后线程 ...
随机推荐
- OSG中的示例程序简介(转)
OSG中的示例程序简介 1.example_osganimate一)演示了路径动画的使用 (AnimationPath.AnimationPathCallback),路径动画回调可以作用在Camera ...
- thinkphp中的HTTP类实现下载
public function test(){ import('ORG.Net.Http'); $filename="Uploads/v1.2.doc"; //exit($file ...
- session销毁
session.invalidate(),session.invalidate的销毁是把这个session所带的用户彻底的销毁,这个session跟用户已经紧密联合在一起,所以就一起销毁了,这样就算换 ...
- mysql的二级索引
mysql中每个表都有一个聚簇索引(clustered index ),除此之外的表上的每个非聚簇索引都是二级索引,又叫辅助索引(secondary indexes). 以InnoDB来说,每个Inn ...
- hive-安装MySQL(centos6.4)
为安装hive做准备,以前装过无数次,在线的.tar包的,一直不用忘得差不多了. centos6.4 虚拟机 先看有没有装,有的话应该是自带的,卸载就可以了 命令分别是 然后在线安装,命令是 (-y是 ...
- C语言第二节概述
学前提醒 其实iOS开发就是开发iPhone\iPad上的软件,而要想开发一款软件,首先要学习程序设计语言 iOS开发需要学习的主要程序设计语言有:C语言.C++.Objective-C,其中C++. ...
- A+B Problem(V)
描述 做了A+B Problem之后,Yougth感觉太简单了,于是他想让你求出两个数反转后相加的值.帮帮他吧 输入 有多组测试数据.每组包括两个数m和n,数据保证int范围,当m和n同时为0是表示输 ...
- C++中枚举定义运算符
由于枚举也是用户定义类型,所以是可以定义运算符, 如: enum Day {sun, mon, tue, wen, thu, fri, sat}; Day& operator++(Day&am ...
- oracle--number
1. oracle的number类型是oracle的内置类型之一,是oracle的最基础数值数据类型.在9iR2及其以前的版本中只支持一种适合存储数值数据的固有数据类型,在10g以后,才出现了两种新的 ...
- CF Two Buttons (BFS)
Two Buttons time limit per test 2 seconds memory limit per test 256 megabytes input standard input o ...