概述

线程池有那些优点:

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. ssh 设置免password登录

    如果: 实现->操作机A机 要以用户"user1"身份.免password登录B机和C机? B机和C机 建立用户 user1 而且能够ssh 登录. A机设置: 1.安装ss ...

  2. zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap

    Dynamic Rankings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...

  3. Ogre分层渲染 (转)

    Ogre分层渲染 转载请注明出处!http://www.cnblogs.com/pulas 在超大的场景中,如果既想看到近处的物体,又想看到很远的物体,则必须把相机的远近裁剪面距离设得很大.远近裁剪面 ...

  4. MaterialDesignLibrary

    https://github.com/navasmdc/MaterialDesignLibrary MaterialDesignLibrary.zip

  5. iOS开发——适配篇&App适配简单概括

    App适配简单概括 1:适配:适应.兼容各种不同的情况 系统适配 针对不同版本的操作系统进行适配 屏幕适配 针对不同大小的屏幕尺寸进行适配 在用户眼中 屏幕是由无数个像素组成的 像素越多,屏幕越清晰 ...

  6. dubbo-RPC学习(二) http protocol

    dubbo中的协议默认支持很多种,从简单的开始,先解读HttpProtocol吧. dubbo中的http-RPC基于spring web支持的http invoker,web容器默认使用jetty. ...

  7. 关于删除linux多余内核

    step 1: 查找当前正在使用的内核文件的版本号 #uname -r step 2: 列出所有的内核文件,使用rpm 或者 dpkg(基于linux系统) 命令  #rpm -q kernel 或者 ...

  8. hive-安装MySQL(centos6.4)

    为安装hive做准备,以前装过无数次,在线的.tar包的,一直不用忘得差不多了. centos6.4 虚拟机 先看有没有装,有的话应该是自带的,卸载就可以了 命令分别是 然后在线安装,命令是 (-y是 ...

  9. Android之ListView常用技巧

    ListView是一个非常常用的列表控件,虽然在5.x时代ListView的风头正在逐渐的被RecyclerView抢去,但是ListView的使用范围依然十分广泛. 接下来的ListView的常用技 ...

  10. ruby 疑难点之—— attr_accessor attr_reader attr_writer

    普通的实例变量 普通的实例变量,我们没法在 class 外面直接访问 #普通的实例变量,只能在 class 内部访问 class C1 def initialize(name) @name = nam ...