线程池 ThreadPool

一般情况下我们都使用Thread类创建线程,因为通过Thread对象可以对线程进行灵活 的控制。但过多创建线程和销毁线程,会消耗掉大量的内存和CPU资源, 假如某段时间内突然爆发了100个短小的线程,创建和销毁这些线程就会消耗很多时间, 可能比线程本身运行的时间还长。为了改善这种状况,.NET提供了一种称之为线程池 (Thread Pool)的技术。线程池提供若干个固定线程轮流为大量的任务服务,比如用10个 线程轮流执行100个任务,当一个线程完成任务时,并不马上销毁,而是接手另一个任务, 从而减少创建和销毁线程的消耗。 线程池由 System.Threading 命名空间中的 ThreadPool 类实现,其部分方法如表 所示。

 ThreadPool 是一个静态类,不必创建实例就可以使用它。一个应用程序最多只有一个 线程池,它会在首次向线程池中排入工作函数时自动创建。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace XianChengChi
{internal class Program{static void Main(string[] args){ThreadPoolTest();Console.ReadKey();  //按下任意键结束程序 }public static void ThreadPoolTest(){//向线程池中添加100个工作线程 for (int i = 1; i <= 100; i++){//ThreadPool.QueueUserWorkItem 是调用线程池来排队工作项的方法//WaitCallback 是一个委托类型,它指向一个没有返回值并接受一个 object 类型参数的方法。ThreadPool.QueueUserWorkItem(new WaitCallback(WorkFunction), i);//当 WorkFunction 被调用时,参数i会被作为 object 类型的参数传入}//创建了一个新的 WaitCallback 委托实例,它指向 WorkFunction 方法}//工作函数 public static void WorkFunction(object n){Console.Write(n + "\t");}}
}

启动程序: 

当需要处理返回值或执行异步操作时,应该考虑使用 Task 或 async/await 关键字 

创建一个返回 Task<TResult> 的方法,其中 TResult 是你期望的返回类型。然后,你可以使用 Task.Run 方法来在线程池上异步执行这个任务,并等待它完成以获取结果。 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace XianChengYiBu
{internal class Program{static async Task Main(string[] args){string n = "Hello";int i = 123;// 使用 Task.Run 和 lambda 表达式来在线程池上异步执行 WorkFunctionAsync  Task<int> task = Task.Run(() => WorkFunctionAsync(n, i));// 等待任务完成并获取结果  int result = await task;// int result = await WorkFunctionAsync("SomeString", 123);// 调用 WorkFunctionAsync 并等待结果  Console.WriteLine("Result: " + result);Console.ReadKey();}//-----------------------   ------------------------------//public static async Task<int> WorkFunctionAsync(string n, int i)//Task<int>,int是返回值{// 模拟一些工作  Console.Write(n + "\t" + i + "\n");// 假设这是某个计算的结果  int result = i * 2;return result;}}
}

 启动程序:

 

 ThreadPool 可以看做容纳线程的容器,我们可通过QueueUserWorkItem()方法把工作函 数排入线程池。

在上面的程序中,我们向线程池中排入了100个工作函数,线程池分别独立的完成了 这100个任务。下面我们研究一下 线程池运行过程中线程数目的变化情况,从而加深对线程池的理解。为了叙述方便,我们 假设下限为10,上限为30。

1.当线程池被创建后,里面就会创建10个空线程(和下限值相同)。 
2.当我们向线程池中排入一个任务后,就会有一个空线程接手该任务,然后运行起
来。随着我们不断向线程池中排入任务,线程池中的空线程逐一运行起来。
3.随着任务的不断增加,在某一时刻任务数量会超出下限,这时线程的数量就不够
用了,但线程池并不会立即创建新线程,而是等待500毫秒左右,这么做的目的是看看在
这段时间内是否有其他线程完成任务并接手这个请求,这样就可以避免因创建新线程而造
成的消耗。如果这段时间内没有线程完成任务,就创建一个新线程去执行新任务。 
4.在任务数量超过下限后,随着新任务的不断排入,线程池中线程数量持续增加,
直至达到上限值为止。 
5.当线程数量达到上限时,继续增加任务,线程数量将不再增加。比如你向线程池
中排入100个任务,则只有30个进入线程池(和上限相同),另外70个在线程池外排队
等待。当线程池中的某个线程完成任务后,并不会立即终止,而是从等待队列中选择一个
任务继续执行,这样就减少了因创建和销毁线程而消耗的时间。 
6.随着任务逐步完成,线程池外部等候的任务被逐步调入线程池,任务的数量逐步
减少,但线程的总数保持恒定,始终为30(和上限值相同)。 
7.随着任务的逐渐减少,总有某一时刻,任务数量会小于上限值,这时线程池内多
余的线程会在空闲2分钟后被释放并回收相关资源。线程数目逐步减少,直到达到下限值
为止。
8.当任务数量减小到下限值之下时,线程池中的线程数目保持不变(始终和下限值
相同),其中一部分在执行任务,另一部分处于空运行状态。 
9.当所有任务都完成后,线程池恢复初始状态,运行10个空线程。 
由上面的论述可以看出线程池提高效率的关键是一个线程完成任务后可以继续为其
他任务服务,这样就可以使用有限的几个固定线程轮流为大量的任务服务,从而减少了因
频繁创建和销毁线程所造成的消耗。 
可见线程池适用于包含包含大量简单线程且这些线程不需要特殊控制的程序,它不但
简单快捷,而且所耗费的系统开销远比Thread少。 
ThreadPool 中的线程不用手动开始,也不能手动取消,你要做的只是把工作函数排入
线程池,剩下的工作将由系统自动完成,也就是说我们不能控制线程池中的线程。如果想
对线程进行更多的控制,那么就不适合使用线程池。在以下情况中不宜使用 ThreadPool
类而应该使用单独的Thread类: 
1. 线程执行需要很长时间(如果有些线程长期占用线程池,那么对在外面排队的任
务说就是灾难); 
2. 需要为线程指定详细的优先级;
3. 在执行过程中需要对线程进行操作,比如睡眠,挂起等。
所以ThreadPool 适合于并发运行若干个运行时间不长且互不干扰的函数。
 
 
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/13152.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SAP_ABAP-思考篇

作为一个SAP十年左右的从业者&#xff0c;其实我很清楚&#xff0c;我自身的能力&#xff0c;确实是很多东西都会一点&#xff0c;但是没有一样是精通的。坦白来说&#xff0c;我的个人简介里&#xff0c;虽然也不算夸大&#xff0c;但我估计有些新手小白看着可能会觉得还挺厉害…

【氮化镓】高电容密度的p-GaN栅电容在高频功率集成中的应用

这篇文章是香港科技大学Kevin J. Chen等人与台积电M.-H. Kwan等人关于高电容密度的p-GaN栅电容在高频功率集成中的应用研究。 文章详细介绍了p-GaN栅电容的设计、特性和在高频功率集成中的应用。通过实验数据和理论分析&#xff0c;文章展示了p-GaN栅电容在实现高电容密度、低…

2.前端路由的配置和使用

一&#xff0c;路由的作用 路由的作用就是将页面文件跟URL地址形成对应匹配 二&#xff0c;如何安装路由 这里我们采用pnpm的方式在项目中执行 pnpm install vue-routernext --save三&#xff0c;路由如何使用 首先创建一个我们需要访问的页面文件&#xff0c;这里我先创建…

二.使用PgAdmin连接Postgresql

二.使用PgAdmin连接Postgresql PostgreSQL是一种开源的对象关系型数据库管理系统(ORDBMS),它支持大部分SQL标准并提供了许多高级功能,例如事务、外键、视图、触发器等。PostgreSQL由PostgreSQL全球开发组维护和开发,它是一种高度可扩展的数据库系统,可以在各种操作系统…

web学习笔记(五十五)

目录 1. 配置代码片段的步骤 2. 条件判断 2.1 v-if、v-else、v-else-if 2.2 v-show 2.3 v-show和v-if的区别 1. 配置代码片段的步骤 在Visual Studio Code中我们可以将常用的代码配置成代码片段&#xff0c;这样就可以在页面上快速输入大段代码了。 &#xff08;1&#…

22 优化日志文件统计程序-按月份统计每个用户每天的访问次数

读取任务一中序列文件&#xff0c;统计每个用户每天的访问次数&#xff0c;最终将2021/1和2021/2的数据分别输出在两个文件中。 一、创建项目步骤&#xff1a; 1.创建项目 2.修改pom.xml文件 <packaging>jar</packaging> <dependencies><dependency>…

HNU-算法设计与分析-作业1

算法设计与分析 计科210X 甘晴void 202108010XXX 前言 这个系列本来想只用一个博客搞定的&#xff0c;谁曾想CSDN对于大批量文字的在线编辑一塌糊涂&#xff0c;感觉走倒车了。只能分成几个博客分别来讲了。后续会有作业-23456。作业重要的是搞懂原因。 文章目录 算法设计与…

【数据结构】时间、空间复杂度实例分析

跌倒了&#xff0c;就重新站起来&#xff0c;继续向前走&#xff1b;傻坐在地上是没用的。&#x1f493;&#x1f493;&#x1f493; 目录 •✨说在前面 &#x1f34b;知识点一&#xff1a;算法的效率 • &#x1f330;1.斐波那契数列的第n项 • &#x1f330;2.算法的复杂度…

001_PyQt简介

本系列面向零基础小白&#xff0c;从零开始到Pyqt 进行项目实战。 什么叫从零开始&#xff1f;从软件安装、环境配置开始。 不跳过一个细节&#xff0c;不漏掉一行代码&#xff0c;不省略一个例图。 PyQt作为一个强大的工具包&#xff0c;成功地将脚本语言python和QT库融合到…

nginx反向代理kafka集群实现内外网隔离访问 —— 筑梦之路

背景说明 我们在使用Kafka客户端连接到Kafka集群时&#xff0c;即使连接的节点只配置了一个集群的Broker地址&#xff0c;该Broker将返回给客户端集群所有节点的信息列表。然后客户端使用该列表信息&#xff08;Topic的分区信息&#xff09;再与集群进行数据交互。这里Kafka列表…

当CV遇上transformer(三)Clip模型及源码分析

当CV遇上transformer(三)Clip模型及源码分析 2020年10月&#xff0c;Dosovitskiy首次将纯Transformer的网络结构应用于图像分类任务中(ViT)&#xff0c;并取得了当时最优的分类效果&#xff0c;其研究成果是Transformer完全替代标准卷积的首次尝试。随着谷歌提出ViT之后&#…

Python 全栈体系【四阶】(四十五)

第五章 深度学习 十、生成对抗网络&#xff08;GAN&#xff09; 1. 图像生成技术概述 1.1 什么是图像生成技术 图像生成技术是指利用机器学习或深度学习等人工智能技术&#xff0c;通过训练模型来生成逼真的图像。这些技术可以根据给定的输入&#xff0c;生成与真实图像相似…

反序列化漏洞【1】

1.不安全的反序列化漏洞介绍 序列化&#xff1a;将对象转换成字符串&#xff0c;目的是方便传输&#xff0c;关键词serialize a代表数组&#xff0c;数组里有三个元素&#xff0c;第一个元素下标为0&#xff0c;长度为7&#xff0c;内容为porsche&#xff1b;第二个元素下标为1…

GPT-4o API 全新版本发布:提升性能,增加性价比

5月13日&#xff0c;OpenAI 发布了全新ChatGPT模型 GPT-4o&#xff0c;它在响应速度和多媒体理解上都有显著提升。在这篇文章中&#xff0c;我们将介绍 GPT-4o 的主要特点及其 API 集成方式。 什么是 GPT-4o&#xff1f; GPT-4o 是 OpenAI 于5月13日发布的最新多模态 AI 模型…

【简单介绍下在Ubuntu中如何设置中文输入法】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

国产化数据库_金仓_Linux版Docker版部署过程及简单使用

国产化数据库金仓Linux版部署过程 文档参考&#xff1a;https://help.kingbase.com.cn/v8/install-updata/install-linux/install-linux-3.html#id12 以下安装是在Centos7系统下进行 0.安装包准备 找到你的操作系统对应的平台所支持的软件包下载&#xff0c;我这里下载的是x…

react的多级路由定义

在写实验室项目的时候&#xff0c;有一个需求&#xff0c;在二级路由页面点击按钮&#xff0c;跳转到详情列表页面&#xff0c;同时三级路由不用在导航栏显示&#xff0c;效果图如下&#xff1a; 前期的尝试&#xff1a; 在route,js文件这样定义的&#xff1a; {path: music,…

mysql权限体系

提示&#xff1a;根据课程视频总结知识点------2024.05.15 文章目录 权限处理逻辑1、 能不能连接2、能不能执行操作 权限授予与回收1、创建用户2、授予权限3、查看权限4、回收权限5、 权限级别 账户安全管理1、用户权限设定原则2、历史文件泄密 用户权限设定原则1. 只读用户--数…

哈希表+DFS快速解决力扣129题:求根节点到叶节点数字之和

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

平均工资数据分析之回归

链接: R语言实战——中国职工平均工资的变化分析——相关与回归分析 1、模型诊断和评估的方法 1. 残差分析 1、残差图 (Residual Plot)&#xff1a;用于检查残差是否存在非随机模式。理想情况下&#xff0c;残差应随机分布在零附近。 2、Q-Q 图 (Quantile-Quantile Plot)&am…