一、什么是ThreadPool 线程池(源码

1.线程池顾名思义,有我们的系统创建一个容器装载着我们的线程,由CLR控制的所有AppDomain共享。线程池可用于执行任务、发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。所以使用线程池不需要自己创建线程,而是通过线程池来创建和执行和管理线程。

二、ThreadPool 线程池和线程的区别

1.ThreadPool 线程池是在.NET 2.0出现的,是一个享元模式整个程序共同享用这一个线程池,当我们的线程执行任务之后它不会立刻销毁,它会回到线程池中,如果有新的任务它就会去执行。避免了我们线程的重复创建和销毁(也不会造成我们CPU的上下文切换的损耗)。

2.大家仔细看一下我前面写的Thread 创建线程执行任务之后,它会自动销毁。那问题来了我们经常的创建、销毁线程这可都是资源的浪费呀!!所以我们要利用每个线程占有的资源。

三、ThreadPool 线程池缺点

1.线程池在性能上优于线程,但是它也是有缺点的。它不支持线程的取消、完成、失败通知等交互性操作。

2.它不能设置池中线程的Name,会增加使用者的难度。

  3.线程池中线程通常都是后台线程,优先级为ThreadPriority.Normal

  4.线程池堵塞会影响我们的性能,阻塞会使CLR错误地认为它占用了大量CPU。CLR能够检测或补偿(往池中注入更多线程),但是这可能使线程池受到后续超负荷的印象。Task (也及时后面要讲的)解决了这个问题。

  5.线程池使用的是全局队列,全局队列中的线程依旧会存在竞争共享资源的情况,从而影响性能(Task 解决了这个问题,方案是使用本地队列)。

四、线程池工作原理

  1.CLR初始化时,线程池中是没有线程的,但是内部有一个操作请求队列,当我们的应用程序使用异步时,会将一个记录项添加到线程池的队列中,线程池队列会自动读取这个记录项,并且发给一个线程池的线程,如果线程池没有线程就会创建一个线程执行这任务,当线程完成任务它不会自动销毁而是回到我们的线程池中,等待线程池派发新的任务。

  2.如果程序给线程池派发了很多任务,线程池也会使用这一个线程执行所有的任务,如果我们的请求速度大于了我们的线程处理速度,就会创建额外线程,就不会导致我们创建了过多的线程。

  2.当我们的线程有大量休息的,它们会在一段时间内自动销毁。这样很好的控制了我们应用程序的性能。

五、ThreadPool 线程池使用

  1.ThreadPool是一个静态类,调用QueueUserWorkItem方法,是可以将一个异步计算放入我们的线程池队列中。

public static bool QueueUserWorkItem(WaitCallback callBack);
public static bool QueueUserWorkItem(WaitCallback callBack, object state);
方法 说明
QueueUserWorkItem 启动线程池里的一个线程(工作者线程)
GetMinThreads 检索线程池在新请求预测中能够按需创建的线程的最小数量。
GetMaxThreads 最多可用线程数,所有大于此数目的请求将保持排队状态,直到线程池线程由空闲。
GetAvailableThreads 剩余空闲线程数。
SetMaxThreads 设置线程池中的最大线程数(请求数超过此值则进入队列)。
SetMinThreads 设置线程池最少需要保留的线程数。

  2.我们可以看到ThreadPool比Thread少了很多的API,被砍掉了

/// <summary>
/// ThreadPool的使用
/// workerThreads  CLR线程池分为工作者线程(workerThreads)
/// completionPortThreads I/O线程(completionPortThreads)
/// </summary>
public static void Show()
{
//使用线程
ThreadPool.QueueUserWorkItem((x) => Running());
ThreadPool.GetAvailableThreads(out int workerThreads, out int completionPortThreads);
Console.WriteLine($"没有设置线程数之前 workerThreads:{workerThreads} completionPortThreads:{completionPortThreads}");
//设置最大的线程数
ThreadPool.SetMaxThreads(, );
//设置最小的线程数
ThreadPool.SetMinThreads(, );
ThreadPool.GetAvailableThreads(out int workerThreads1, out int completionPortThreads1);
Console.WriteLine($"设置最大的线程数之后 workerThreads:{workerThreads1} completionPortThreads:{completionPortThreads1}");
Console.ReadLine();
}

  3.我们要注意的就是堵塞线程的时候一定要做好处理,最好是不要堵塞我们的线程,不然很容易造成死锁GG

        /// <summary>
/// ThreadPool 线程等待
///类 包含了一个bool属性
///false--WaitOne等待--Set--true--WaitOne直接过去
///true--WaitOne直接过去--ReSet--false--WaitOne等待
///https://www.cnblogs.com/howtrace/p/11362284.html
/// </summary>
public static void Show1()
{
//设置最大的线程数
ThreadPool.SetMaxThreads(, );
//设置最小的线程数
ThreadPool.SetMinThreads(, );
//设置false使用WaitOne()会直接堵塞线程,不会释放 、Set()设置为true
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
//设置false使用WaitOne()会直接堵塞线程,不会释放 、Set()设置为true
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
//上面两种方法都是可以拦截线程,都是继承EventWaitHandle 接口
//就都具有Reset() //红灯 设置为false导致线程等待
//Set() //绿灯 设置为true 启动线程继续执行
//WaitOne() // 等待信号 会根据我们线程状态执行,为true不需要等待直接执行
//反之为false会等待线程状态为true才会执行 //不同点 ManualResetEvent AutoResetEvent
//ManualResetEvent 在·使用Set()的时候会所有处理 WaitOne 状态线程均继续执行。
//AutoResetEvent 在使用Set()的时候会执行一个线程其他的线程继续等待执行。 for (int i = ; i < ; i++)
{
var k = i;
ThreadPool.QueueUserWorkItem(x =>
{
Console.WriteLine(k);
if (k < )
{
//等待线程,但是上面我们只开了16个线程,结果我18个线程全部等待
//导致了死锁
manualResetEvent.WaitOne();
}
else
{
//恢复执行状态
manualResetEvent.Set();
}
});
if (manualResetEvent.WaitOne())
{
Console.WriteLine("没有死锁、、、");
}
Console.WriteLine("等着QueueUserWorkItem完成后才执行");
}
Console.ReadLine();
}

多线程之旅(ThreadPool 线程池)的更多相关文章

  1. C#多线程之旅(3)——线程池

    v博客前言 先交代下背景,写<C#多线程之旅>这个系列文章主要是因为以下几个原因:1.多线程在C/S和B/S架构中用得是非常多的;2.而且多线程的使用是非常复杂的,如果没有用好,容易造成很 ...

  2. 【多线程】-ThreadPool线程池

    ThreadPool介绍: Thread类是一个静态类,所有不存在实例化构造函数操作,直接可以调用其内所存在的方法. 微软官网给出的解释: 提供一个线程池,该线程池可用于执行任务.发送工作项.处理异步 ...

  3. java多线程总结五:线程池的原理及实现

    1.线程池简介:     多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.        假设一个服务器完成一项任务所需时间为:T1 创 ...

  4. C# 多线程的自动管理(线程池) 基于Task的方式

    C# 多线程的自动管理(线程池) 在多线程的程序中,经常会出现两种情况:    1. 应用程序中线程把大部分的时间花费在等待状态,等待某个事件发生,然后给予响应.这一般使用 ThreadPool(线程 ...

  5. 浅谈ThreadPool 线程池

    本文来自:http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html 相关概念: 线程池可以看做容纳线程的容器: 一个应用程序最多只能有 ...

  6. 多线程(七)JDK原生线程池

    如同数据库连接一样,线程的创建.切换和销毁同样会耗费大量的系统资源.为了复用创建好的线程,减少频繁创建线程的次数,提高线程利用率可以引用线程池技术.使用线程池的优势有如下几点:        1.保持 ...

  7. java核心-多线程(6)-线程池-ThreadPoolExecutor

    1.java多线程编程少不了使用线程池,线程池相关的工具类所在jdk包,java.util.concurrent 2.使用示例 demo1 public class ThreadPoolDemo { ...

  8. ThreadPool线程池 小结

    ThreadPool类提供一个线程池,该线程池可用于发送工作项.处理异步 I/O.代表其他线程等待以及处理计时器 线程池通过为应用程序提供一个由系统管理的辅助线程池使您可以更为有效地使用线程.一个线程 ...

  9. 转载【浅谈ThreadPool 线程池】

    浅谈ThreadPool 线程池 http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html

随机推荐

  1. Turn and Stun server · J

    本文简介了Turnserver(Turn + Stun)服务器的搭建.Turnserver主要提供了stun服务,支撑NAT.防火墙穿透,turn服务器,支撑打洞失败时的数据中转.使用场景上类似于前端 ...

  2. 为何滴滴会走Uber之路,研发无人驾驶?

    近日,滴滴出行宣布完成新一轮超过55亿美元融资,以支持其全球化战略的推进和前沿技术领域的投资.其中,无人驾驶汽车将是这笔资金重要的投资方向.此前,滴滴在全球范围内的追赶对象Uber不断在无人汽车领域发 ...

  3. 解决sendmail发送邮件慢的问题

    sendmail默认会先监听本机的邮件服务,如果本机邮件服务访问不了,在访问其他的邮件服务器 自己测试将本机主机名(通过hostname命令查看)从/etc/hosts中删除,发送邮件的速度就非常快了 ...

  4. 【转载】Java for循环

    转载只为个人学习,阅读请前往原地址:Java for循环的几种用法详解 本文主要是来了解一下Java中的几种for循环用法,分析得十分详细,一起来看看. J2SE 1.5提供了另一种形式的for循环. ...

  5. 20170220-coroutine

    协程 coroutine 最近频繁的听说到 "协程" 这个词,花了一段时间肤浅的研究了一下.对于 "它是一个什么东西" 有了一个大概的了解. from wiki ...

  6. SpringBoot快速上手系列01:入门

    1.环境准备 1.1.Maven安装配置 Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件. 下载Maven可执行文件 cd /usr/local ...

  7. Spring MVC知识梳理

    同上一篇博客,复习梳理SpringMVC知识点,这次的梳理比较快,很多细节没有顾虑到,后期可能会回来补充 1. 整体架构 1.1 在学习了SSM框架后我们来理清三者的应用层面 浏览器发送请求,请求到达 ...

  8. win10安装LoadRunner时,安装.net framwork组件报0x800F081F错误 解决办法

    一.报错原因 0x800F081F错误大多数是在安装软件时,系统无法联网自动下载安装. 经过各种排查及搜索解决方案,总结原因无非以下三种: 1.windows update被禁用. 2.电脑没有.ne ...

  9. 前端面试题-HTML语义化标签

    一.HTML5语义化标签 标签 描述 <article> 页面独立的内容区域. <aside> 页面的侧边栏内容. <bdi> 允许您设置一段文本,使其脱离其父元素 ...

  10. VUE实现Studio管理后台(九):开关(Switch)控件,输入框input系列

    接下来几篇作文,会介绍用到的输入框系列,今天会介绍组普通的调用方式,因为RXEditor要求复杂的输入功能,后面的例子会用VUE的component动态调用,就没有今天的这么直观了,控件的实现原理都一 ...