概述

线程池有那些优点:

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. SAP标准教材列表

    AC010 mySAP Financials Overview to Financial Accounting and ReportingAC020 mySAP Financials Investme ...

  2. C#程序实现动态调用DLL的研究[转]

    摘   要: 在< csdn 开发高手> 2004 年第 03 期中的<化功大法——将 DLL 嵌入 EXE >一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在 ...

  3. myeclipse-10.7-offline-installer-windows安装图解及注意事项

    MyEclipse企业级工作平台(MyEclipseEnterprise Workbench ,简称MyEclipse)是对EclipseIDE的扩展,利用它我们能够在数据库和JavaEE的开发.公布 ...

  4. PHP实现Web Service(转)

    1.OAuth OAUTH协议为用户资源的授权提供了一个安全的.开放而又简易的标准.与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码)  2.SCA 服务组件 ...

  5. Linux shell 脚本攻略之批量重命名

    摘自:<Linux shell 脚本攻略>

  6. Android基本控件之RadioGroup

    我们在手机上经常看到一堆选项,但是我们只能选择一个,那么在Android中,这个控件就叫做RadioButton,也就是单选按钮的意思,他们之所以能够达到只能选择一个的效果,是因为有一个RadioGr ...

  7. 小白日记13:kali渗透测试之服务扫描(三)-SMTB扫描、防火墙识别、负载均衡识别、WAF识别

    SMTP扫描 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式.SMTP协议属于TCP/ ...

  8. iOS实现自定义的弹出视图(popView)

    前段时间,在项目中有个需求是支付完成后,弹出红包,实现这么一个发红包的功能.做了最后,实现的效果大致如下: 一.使用方法 整个ViewController的代码大致如下 // //  SecondVi ...

  9. 深入理解 GCD

    前言 首先提出一些问题: dispatch_async 函数如何实现,分发到主队列和全局队列有什么区别,一定会新建线程执行任务么? dispatch_sync 函数如何实现,为什么说 GCD 死锁是队 ...

  10. Debian 7 安装 Emacs 24.3

    Emacs 24.3出来好久了,但是在Debian 7里还是Emacs 23的版本. 以下是安装步骤(9步): -dev libncurses5-dev autoconf automake texin ...