多线程是一个不会过时的话题,因为每个开发的成长必然要掌握这个知识点,否则半懂不懂怎么保证系统的可靠性和性能,其实在网上随便一搜都会有海量的文章说这个话题,大多数写得很细写得非常好,但发现很少有概览性的文章,我希望能借本文给大家一个全局视野,结合多年实践帮大家快速学习或者回顾思考,对感兴趣的知识点再深入学习了解。

一、知识点概括

二、具体实例演示如何实现

> Thread 多线程最基础的类

//ThreadPool.GetMaxThreads(out int maxTCount, out int maxPCount);
//ThreadPool.GetMinThreads(out int minTCount, out int minPCount);
//ThreadPool.SetMaxThreads(maxTCount, maxPCount);// 调整最大线程数
//ThreadPool.SetMinThreads(minTCount, minPCount);// 调整最小线程数 long tick = C_ITEM_COUNT;
ManualResetEvent signal = new ManualResetEvent(false);
Console.WriteLine("========== 示例:采用Thread执行处理 ==========");
for (int i = ; i < C_ITEM_COUNT; i++)
{
new Thread((obj) =>
{
Thread.Sleep();
Console.Write(" {0} ", obj);
if (Interlocked.Decrement(ref tick) == )
signal.Set();
}).Start(i);
}
Console.Write(" 等待子线程执行 ");
signal.WaitOne();
Console.WriteLine();
Console.WriteLine("全部线程执行完毕,按任意键继续...");

> ThreadPool 线程池,XX池的概念可以广泛应用于其他资源管理,例如字体池(防句柄泄露)、短信猫池等等

tick = C_ITEM_COUNT;
signal.Reset();
Console.WriteLine();
Console.WriteLine("========== 示例:采用ThreadPool执行处理 ==========");
for (int i = ; i < C_ITEM_COUNT; i++)
{
ThreadPool.QueueUserWorkItem((obj) =>
{
Thread.Sleep();
Console.Write(" {0} ", obj);
if (Interlocked.Decrement(ref tick) == )
signal.Set();
}, i);
}
Console.Write(" 等待子线程执行 ");
signal.WaitOne();
Console.WriteLine();
Console.WriteLine("全部线程执行完毕,按任意键继续...");

> Task 任务,功能丰富用法灵活。结合现实生活用字面意思去理解就好:可以同时做多个任务,任务做完可以接着做其他任务,任务可能会取消等等。

tick = C_ITEM_COUNT;
signal.Reset();
Console.WriteLine();
Console.WriteLine("========== 示例:采用Task执行处理,注意取消了处理{0}的进程 ==========", C_ITEM_COUNT - );
var tasks = new Tuple<Task, CancellationTokenSource>[C_ITEM_COUNT];
for (int i = ; i < C_ITEM_COUNT; i++)
{
var cts = new CancellationTokenSource();
var task = Task.Factory.StartNew((obj) =>
{
Thread.Sleep();
Console.Write(" {0} ", obj);
}, i, cts.Token);
task.ContinueWith((t) =>
{
if (Interlocked.Decrement(ref tick) == )
signal.Set();
});
tasks[i] = new Tuple<Task, CancellationTokenSource>(task, cts);
} tasks[C_ITEM_COUNT - ].Item2.Cancel();// 取消线程。 Console.Write(" 等待子线程执行 ");
signal.WaitOne();
Console.WriteLine();
Console.WriteLine("全部线程执行完毕,按任意键继续...");

> Parallel 并行

tick = C_ITEM_COUNT;
signal.Reset();
Console.WriteLine();
Console.WriteLine("========== 示例:采用Parallel执行处理 ==========");
Parallel.For(, C_ITEM_COUNT, obj =>
{
Thread.Sleep();
Console.Write(" {0} ", obj);
if (Interlocked.Decrement(ref tick) == )
signal.Set();
}); Console.Write(" 等待子线程执行 ");
signal.WaitOne();
Console.WriteLine();
Console.WriteLine("全部线程执行完毕,按任意键继续...");

以上示例执行结果如下,重点可以关注下"等待子线程执行"这个节点,理解主线程和各子线程的优先执行顺序

三、性能对比(理解线程池技术的性能也可以通过最大最小线程数调节)

> 循环数:200,线程池参数:默认

> 循环数:200,线程池参数:50 - 1000

> 循环数200,线程池参数:100-1000

> 循环数200,线程池参数:200-1000

最大线程数 ~ 最小线程数 Thread(ms) ThreadPool(ms) Task(ms) Parallel(ms)
2047/1000 ~ 12/12 2712.09 8057.14 8585.01 7526.57
1000/1000 ~ 50/50 2733.25 2289.96 2218.29 3660.33
1000/1000 ~ 100/100 2503.08 1620.73 1534.50 1742.78
1000/1000 ~ 200/200 2999.27 1436.24 1150.21 935.22

 四、结论

> Thread就像脱缰的野马,不受控制,创建多少就运行多少,可能少量时效率是高了,量大的时候除了性能没优势,还可能导致句柄泄露。

> ThreadPool与Task类似,但Task相比效率更高用法更灵活。

> Parallel自带了同步功能,不需要用信号量来做额外的同步等待。

> ThreadPool、Task、Parallel的性能都取决于线程池最大线程数和最小线程数。

> 推荐使用 Task 和 Parallel,具体用哪个可以参考用法自己斟酌。

.NET多线程知识快速学习的更多相关文章

  1. 第23篇 js快速学习知识

    前面说了js的一些高级方面的基础知识,这些都是比较容易出错的和比较难理解的东西,除了这些之外其它的知识都比较简单了,基础学好了,扩展起来就是小意思.今天说说js方面可以快速学习和入门的知识. 1.闭包 ...

  2. 看我如何快速学习.Net(高可用数据采集平台)

    最近文章:高可用数据采集平台(如何玩转3门语言php+.net+aauto).高并发数据采集的架构应用(Redis的应用) 项目文档:关键词匹配项目深入研究(二)- 分表思想的引入 吐槽:本人也是非常 ...

  3. 阿里巴巴Java开发手册快速学习

    Java作为一门名副其实的工业级语言,语法友好,学习简单,大规模的应用给代码质量的管控带来了困难,特别是团队开发中,开发过程中的规范会直接影响最终项目的稳定性. 善医者“未有形而除之”,提高工程健壮性 ...

  4. Javaweb快速学习

    孙卫琴老师的javaweb一书已经买了很多年,由于很厚一直也没有去好好阅读下, 项目发布后有闲暇时间,决定快速学习了,毕竟很多概念和知识主要还是复习. 对于互联网,我们可以简单认为浏览器就是会人类语言 ...

  5. Vue 超快速学习

    Vue 超快速学习 基础知识: 1.vue的生命周期: beforeCreate/created. beforeMount/mounted. beforeUpdate/updated. beforeD ...

  6. 20155321 《信息安全系统设计》Linux多线程的深入学习

    再次学习之多线程 基本概念的再次学习 线程是程序执行的最小单位(进程是资源管理的最小单位),线程隶属于某个进程中 进程有自己的数据段.代码段和堆栈段.线程通常叫做轻型的进程,每个线程共享其所附属进程的 ...

  7. 一点记忆—— Java框架知识的学习有感

    一点记忆—— Java框架知识的学习有感         说一下自己学习的框架知识的历程吧:好久了,应该是一年前,也就是大三上的时候,我对于基本的 Java编程就已经达到所谓的“熟练”,认为自己可以在 ...

  8. (*)(转)要快速学习SSM框架,你需要一套学习曲线平滑的教程

    作者:meepo链接:https://www.zhihu.com/question/57719761/answer/156952139来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...

  9. 【原创】docker在Ubuntu下1小时快速学习

    前言 由于工作原因,很多情况下需要快速学习新的知识,针对docker如果从头到尾看相关书籍学习会非常慢,所以整理了下docker的常用操作,只要跟着本文学习操作,一小时就能掌握docker大部最常用分 ...

随机推荐

  1. 使用where 过滤数据

    --本章主要内容是MySQL中使用where搜索条件进行过滤数据. where条件在from子句后面给出,如下所示: select name,price from shops where price& ...

  2. So Easy - 在Linux服务器上部署 .NET Core App

    .NET Core 是微软提供的免费.跨平台和开源的开发框架,可以构建桌面应用程序.移动端应用程序.网络应用程序.物联网应用程序和游戏应用程序等.如果你是 Windows 平台下的 dotnet 开发 ...

  3. java基础-类成员访问权限控制

    一 前言 这篇文章是很基础的一文,没多大深度,对于开发人员必然是熟练于心.本篇文章的主题是为什么java要设置类成员访问级别?其原因也很简单,就是为了面向对象的封装特性:将类成员使用不同的访问级别控制 ...

  4. springcloud-eureka高可用集群搭建

    一 前言 eureka作为注册中心,其充当着服务注册与发现功能,加载负载均衡:若在项目运行中eureka挂了,那么整个服务整体都会暂停,所以为服务运行的安全性,有必要搭建eureka集群:当其中一个e ...

  5. TP5中find_in_set的用法

    TP5.1.22版本 $id=4; Db::name('menu')->where('FIND_IN_SET(:id,pid_all)',['id' => $id])->update ...

  6. 我也开源... React Native Messager

    近期有空,玩转React Native. https://github.com/andyc365/ReactNativeMessager React Native Messager A React N ...

  7. Redis简单命令(部分示例代码)

    一.redis文件夹下的可执行文件(文章尾部有示例代码) 可执行文件 作用 redis-server 启动redis redis-cli redis命令行工具 redis-benchmark 基准测试 ...

  8. JavaScript图形实例:纺织物图案

    1.简单纺织物图案 先在HTML页面中设置一个画布. <canvas id="myCanvas" width="360" height="240 ...

  9. 传统js和jsx与ts和tsx的区别

    一.从定义文件格式方面说 1.传统的开发模式可以定义js文件或者jsx文件2.利用ts开发定义的文件格式tsx二.定义state的状态来说 1.传统的方式直接在构造函数中使用 constructor( ...

  10. weed3-1.hello world

    Weed3 一个微型ORM框架(只有0.1Mb哦) 源码:https://github.com/noear/weed3 源码:https://gitee.com/noear/weed3 05年的时候开 ...