多线程系列(三)之线程池
时间:2022-07-23
本文章向大家介绍多线程系列(三)之线程池,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
什么是线程池?
.NetFramework1.0时代的Thread,API功能繁多,对线程的数量是没有管控的,在.NetFramework2.0时代推出了ThreadPool,如果某个对象创建和销毁代价比较高,同时这个对象还可以反复使这些线程,就需要使用线程池,线程池可以保存多个线程对象,需要使用线程时直接从线程池里面拿,使用完之后不做释放,又放回池子(享元模式),需要用的时候再去拿。这样可以减少创建线程的开销,提升性能,此外,还可以管控线程的总数量,防止资源滥用。
委托异步调用、Task、Parrallel、async/await的线程全部都是线程池里面的线程。直接new Thread开起的线程不受线程池的数量限制(但是会占用线程池的线程数量)。
使用线程池开启线程
ThreadPool.QueueUserWorkItem(o=>this.DoSomeThing("btnThreadPool_Click_1"));
ThreadPool.QueueUserWorkItem(o => {
this.DoSomeThing("btnThreadPool_Click_2");
Console.WriteLine( o?.ToString());
}, "wjl");
检索和设置线程池的最大最小数目和异步IO线程的最大最小数目
I/O线程是.NET专为访问外部资源所设置的一种线程,因为访问外部资源常常要受到外界因素的影响,为了防止让主线程受影响而长期处于阻塞状态,.NET为多个I/O操作都建立起了异步方法。
//检索由 GetMaxThreads 返回的线程池线程的最大数目和异步IO线程的最大数目
ThreadPool.GetMaxThreads(out int workerThreads, out int completionPortThreads);
Console.WriteLine($"当前线程池最大数目为:{workerThreads},最大异步IO线程:{completionPortThreads}");
//检索由 GetMinThreads 返回的线程池线程的最小数目和异步IO线程的最小数目
ThreadPool.GetMinThreads(out int workerThreadsMin, out int completionPortThreadsMin);
Console.WriteLine($"当前线程池最小数目为:{workerThreadsMin},最小异步IO线程:{completionPortThreadsMin}");
ThreadPool.SetMaxThreads(8, 8);//设置的最大值,必须大于CPU核数,否则设置无效
ThreadPool.SetMinThreads(2, 2);
线程等待
单个线程等待:
//线程等待
ManualResetEvent mre = new ManualResetEvent(false);
//ManualResetEvent是一种信号量的方式
//如果初始为false--关闭, mre.Set()之后变为ture,WaitOne就能通过
//如果初始为tue--打开, mre.Rset()之后变为false,WaitOne就只能等待
ThreadPool.QueueUserWorkItem(o => {
this.DoSomeThing("btnThreadPool_Click_3");
mre.Set();
});
mre.WaitOne();
Console.WriteLine("任务已经完成了...");
多个线程等待:
ManualResetEvent[] mres = new ManualResetEvent[10];
for (int i = 0; i < 10; i++)
{
mres[i] = new ManualResetEvent(false);
int k = i;
ThreadPool.QueueUserWorkItem(o =>
{
this.DoSomeThing($"mres{k}");
ManualResetEvent mre = o as ManualResetEvent;
mre.Set();
}, mres[i]);
}
//等待所有数组中的元素都收到信号,如果是控制台程序或者winform程序,请将Main()函数上面的特性[STAThread]注释掉
WaitHandle.WaitAll(mres);
Console.WriteLine("多个任务已经完成了...");
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Octave数据运算基础教程-ML Note29
- Octave中数据的可视化—ML Note 30
- matplotlib animation FuncAnimation画2D线图
- 坚持一下只需要一个理由就够了
- IGD反转世代距离-多目标优化评价指标概念及实现
- webpack实战——样式文件分离
- matlab绘图工具
- python批量移动文件&重命名代码分享
- [DeeplearningAI 笔记]第一章2.11-2.16 向量化与 python/numpy 向量说明
- 自己动手作图深入理解二叉树、满二叉树及完全二叉树
- Matlab矩阵加入新元素
- 每个Python程序员都应该知道的10个缩写
- 《剑指offer》第九天:斐波那契数列
- [tensorflow损失函数系列]sigmoid_cross_entropy_with_logits
- 0794-5.16.2-Hive和Imapla查询decimal类型结果不同异常