概述

线程池有那些优点:

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# 线程--第三线程池的更多相关文章

  1. linux线程篇 (三) 线程的同步

    1 互斥量 pthreat_mutex_t mymutex; //1. 创建 初始化 int pthread_mutex_init(pthread_mutex_t *mutex, const pthr ...

  2. 线程池 异步I/O线程 <第三篇>

    在学习异步之前先来说说异步的好处,例如对于不需要CPU参数的输入输出操作,可以将实际的处理步骤分为以下三步: 启动处理: 实际的处理,此时不需要CPU参数: 任务完成后的处理: 以上步骤如果仅仅使用一 ...

  3. 转载 线程池 异步I/O线程 <第三篇>

    在学习异步之前先来说说异步的好处,例如对于不需要CPU参数的输入输出操作,可以将实际的处理步骤分为以下三步: 启动处理: 实际的处理,此时不需要CPU参数: 任务完成后的处理: 以上步骤如果仅仅使用一 ...

  4. 转:专题三线程池中的I/O线程

    上一篇文章主要介绍了如何利用线程池中的工作者线程来实现多线程,使多个线程可以并发地工作,从而高效率地使用系统资源.在这篇文章中将介绍如何用线程池中的I/O线程来执行I/O操作,希望对大家有所帮助. 目 ...

  5. 第三十四天- 线程队列、线程池(map/submit/shutdown/回调函数)

    1.线程列队 queue队列 :使用import queue,用法与进程Queue一样 class queue.Queue(maxsize=0) # 先进先出: q = queue.Queue(3) ...

  6. JAVA多线程(三) 线程池和锁的深度化

    github演示代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-servic ...

  7. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

  8. java线程API学习 线程池ThreadPoolExecutor(转)

    线程池ThreadPoolExecutor继承自ExecutorService.是jdk1.5加入的新特性,将提交执行的任务在内部线程池中的可用线程中执行. 构造函数 ThreadPoolExecut ...

  9. (转)Java结束线程的三种方法

    背景:面试过程中问到结束线程的方法和线程池shutdown shutdownnow区别以及底层的实现,当时答的并不好. Java结束线程的三种方法 线程属于一次性消耗品,在执行完run()方法之后线程 ...

随机推荐

  1. 【不积跬步,无以致千里】VIM查找替换归纳总结zz

    http://spaces.msn.com/dingy/blog/cns!2F24B9E66A542581!327.entry VIM中常用的替换模式总结. 1,简单替换表达式 替换命令可以在全文中用 ...

  2. ADO.NET 快速入门(七):使用数据库事务

    数据库事务用于控制数据提交到数据库.例如,在标准的账户程序,账户的借贷必须同时完成.由于电脑偶尔发生故障(电力中断.网络中断,等等),可能有些记录被更新或者添加,但是另外一些没有.为了避免这些情况,可 ...

  3. SqlServer刷新所有视图

    CREATE PROCEDURE RefreshAllView AS DECLARE MyCursor CURSOR FOR select Name from dbo.sysobjects where ...

  4. spring读取properties的方法

    首先在配置文件中配置PropertyPlaceholderConfigurer 单个配置文件: <bean id="propertyConfigurer" class=&qu ...

  5. android短信的接收和发送处理

    一 初始化 手机开机初始化调用GSMPhone 构造函数. GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifie ...

  6. iOS开发——语法篇&swift经典语法总结

    swift经典语法总结 1:函数 1.1 func funcNmae()->(){} 这样就定义了一个函数,它的参数为空,返回值为空,如果有参数和返回值直接写在两个括号里就可以了 1.2 参数需 ...

  7. visualvm连接服务器jvm进行监控

    本地环境,mac: 服务器环境ubuntu: 直接运行jstatd命令,提示 Could not create remote object access denied ("java.util ...

  8. python 学习(一)

    python的基础看完了之后,有点像简化并提供了一定优化后的java基础,看java多了的人看python还是比较别扭的.看完别人对于java和python的对比,我只能感慨一句,还有什么是java办 ...

  9. 高级I/O之STREAMS

    http://en.wikipedia.org/wiki/STREAMS STREAMS(流)是系统V提供的构造内核设备驱动程序和网络协议包的一种通用方法,对STREAMS进行讨论的目的是为了理解系统 ...

  10. Hummer框架平台介绍

    三年工作过程中经常会用到使用Java开源框架,但经常会遇到重新组合比较麻烦,本次采用目前主流开源框架及插件整理出一套融合开发.测试.部署整个流程的平台. 本平台采用Hummer代号,是悍马和蜂鸟分意思 ...