-Begin-

前言

初学者学习编程时,很容易因为多线程出现各种问题,导致不敢使用多线程。但是多线程技术在做开发中,是不可忽视的一个技术,基本上我们实际应用中,每个项目都会使用多线程,所以多线程技术必须掌握。

为什么要用多线程

随着工业的进步,现在的笔记本、台式机大都是双核的,4核、8核甚至16核,也很常见,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%。

单核CPU上所谓的”多线程”那是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程”同时”运行罢了。

多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的。

如果你做项目不使用多线程,不仅是技术的问题,也是对电脑资源的极大浪费,就像你买了一辆配置非常高的越野车,你仅仅只用它来日常代步一样。

为什么不敢用多线程

之前跟一些学员沟通时发现,很多学员之所以不敢使用多线程,是因为之前出过问题,有种“一朝被蛇咬,十年怕井绳”的感觉。

为什么多线程容易出问题,有个主要的原因在于多线程充满着“未知性”,有的人使用时,发现代码并没有按照预想的流程在走,这其实是正常的。

我们必须要明确一点,多线程确实是“不可控的”,有某种意义上来说,(需要代码加VX:xiketang777)多线程是靠CPU调度来执行的,并非人为去控制。

我们所谓的控制多线程,仅仅是.NET框架开放了一些接口给开发者,这样可以相对性地间接控制多线程的启动停止暂停继续。

线程的启动停止

线程的启动停止,(需要多线程资料加VX:xiketang777)从.Net Framework 4.5开始,Task提供了一个叫CancellationTokenSource的对象,可以使用它来对多线程的启停进行控制。

首先,我们做一个线程任务,这个任务很简单,只是不断操作某个变量,每0.1秒加1,到一定值之后,重置为0,然后将这个值显示在界面上,界面如下所示:

所以任务方法如下:

        /// <summary>/// 多线程执行方法/// </summary>private void TaskMethod(){while (!cts.IsCancellationRequested){CurrentValue++;if (CurrentValue == 200){CurrentValue = 0;}Thread.Sleep(100);}}

我们可以看到在方法里调用了一个cts对象,这个对象就是CancellationTokenSource的对象,因此我们需要创建一个CancellationTokenSource对象cts:

        /// <summary>/// 线程启停控制/// </summary>private CancellationTokenSource cts;

然后在启动线程按钮的事件里,编写代码如下:

        private void btn_Start_Click(object sender, EventArgs e){cts = new CancellationTokenSource();Task.Run(() =>{TaskMethod();}, cts.Token);}

停止线程按钮的事件里,只需要调用cts的Cancel方法即可:

        private void btn_Stop_Click(object sender, EventArgs e){cts.Cancel();CurrentValue = 0;}

其实,说白了,就是通过cts来控制cts的IsCancellationRequested属性,进而实现多线程的控制。

线程的暂停继续

多线程的暂停继续,.NET为我们提供了另外一个对象——ManualResetEvent,这个对象会有一个值,这个值是布尔类型,就像一个门闸一样,True是打开门闸,False是关闭门闸,所以想要暂停多线程就调用这个对象的Reset方法,想要继续多线程就调用这个对象的Set方法,使用非常简单。

首先我们创建一下这个对象,可以通过构造方法,给这个对象赋初始值,(需要多线程资料加VX:xiketang777)我这里为True,这样就能直接运行,不会阻塞。

        /// <summary>/// 线程暂停控制,默认开启/// </summary>private ManualResetEvent manual = new ManualResetEvent(true);

但是如果希望这个对象与多线程有所联系,必须要在多线程的方法里体现这个对象的作用,这个是调用这个对象的WaitOne方法,表示在调用的地方阻塞住,通过判断True或者False来决定是否继续执行,就像大家开车过高速收费站一样,即使现在普遍采用ETC了,在入口也需要减速,有一个ETC识别的过程,识别成功才会抬杆,识别识别,杆子是不会自动抬起的,这个是一样的道理。

所以线程执行代码如下:

        /// <summary>/// 多线程执行方法/// </summary>private void TaskMethod(){while (!cts.IsCancellationRequested){manual.WaitOne();CurrentValue++;if (CurrentValue == 200){CurrentValue = 0;}Thread.Sleep(100);}}

对比一下,其实就是加了一个manual.WaitOne()。

线程暂停代码:

        private void btn_Pause_Click(object sender, EventArgs e){manual.Reset();}

线程继续代码:

        private void btn_Continue_Click(object sender, EventArgs e){manual.Set();}

AutoResetEvent

AutoResetEvent和ManualResetEvent的用法非常相似,区别在于一个是手动,一个是自动,AutoResetEvent会在置位之后自动复位,这样体现在多线程里,就是会只执行一次,就像大家进小区一样,如果有10辆车在排队,这时候如果自动模式,每次只能进一辆车,如果是手动模式,可以由保安控制门闸打开,等10辆车都进去之后,再由保安将门闸关注。

多线程启动停止暂停继续相关推荐

  1. C++多线程启动、暂停、继续与停止

    在自动化设备中,设备在运转过程中,为了防止设备伤人,通常会在设备门入口安装光幕,当光幕被遮挡时,设备必须暂停,确保安全的情况下,按下继续按钮,设备继续运转.对于多工位的设备,每个工位可能交由一个线程处 ...

  2. c#语言窗体运行暂停指令,C#线程启动、暂停、恢复、停止怎么实现

    论坛的高手你们好,本人是一个菜鸟,肯请大家帮个忙实现如下功能: 首先窗体界面如下: 怎么实现"start"启动线程."pause"暂停线程."resu ...

  3. WindowsPowerShell 停止、启动、暂停和重启服务、卸载服务

    PowerShell 停止.启动.暂停和重启服务.卸载服务 PowerShell 停止.启动.暂停和重启服务 官文 powershell卸载服务 官文 目录 PowerShell 停止.启动.暂停和重 ...

  4. Windows下启动停止SQL Server 2005服务

    很多技术爱好者的电脑上总是安装了很多软件,包括应用软件.开发工具软件及数据库软件,但是随着时间的流逝,慢慢地电脑上装的软件已经超出了电脑本身所能承载的量了,因而出现了电脑运行速度慢等问题.同时,也有一 ...

  5. 美团因拖欠骑手工资被约谈;传苹果6月6日举办全球开发者大会;Linux 5.18开始启动停止支持ReiserFS|极客头条

    「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 整理 | 梦依丹 出品 | CSDN(ID:CSDNnews ...

  6. windows:服务启动、暂停、停止按钮不能点击,是灰色如何解决

    最近在使用mysql的时候发现mysql服务器启动.暂停.停止按钮不能点击,是灰色. 查询网上的文章发现,如果服务不是正常停止,那么服务有些线程还在用,就需要手动找到并关闭线程即可.成功关闭后,那么几 ...

  7. springboot集成kafka消费手动启动停止

    项目场景: 在月结,或者某些时候,我们需要停掉kafka所有的消费端,让其暂时停止消费,而后等月结完成,再从新对消费监听恢复,进行消费,此动作不需要重启服务,最后源码下载 解决分析 KafkaList ...

  8. 【转】Linux Oracle服务启动停止脚本与开机自启动

    在CentOS 6.3下安装完Oracle 10g R2,重开机之后,你会发现Oracle没有自行启动,这是正常的,因为在Linux下安装Oracle的确不会自行启动,必须要自行设置相关参数,首先先介 ...

  9. java线程开启不了_Java中多线程启动,为什么调用的是start方法,而不是run方法?...

    前言 大年初二,大家新年快乐,我又开始码字了.写这篇文章,源于在家和基友交流的时候,基友问到了,我猛然发现还真是这么回事,多线程启动调用的都是start,那么为什么没人掉用run呢?于是打开我的ide ...

最新文章

  1. JNI调用(github有代码可下载)
  2. vim编辑环境设定[Linux]
  3. DK云网关与普通DTU之间的区别
  4. GPU 编程入门到精通(一)之 CUDA 环境安装
  5. 【STM32】DMA详解
  6. delphi5开发人员指南_成为企业家并发挥作用的开发人员指南
  7. 人工智能之入门大数据
  8. Pannellum:详解利用Pannellum实现Web三维全景功能
  9. 冀教版四年级上册计算机教案,冀教版信息技术四年级上册教案
  10. 微信群机器人管理系统源码+支持同登陆多号
  11. linux下文件恢复方法,Linux下误删文件恢复办法
  12. 百度搜索算法全解析SEO课程笔记
  13. SQl语句学习专题(转)
  14. java 高效列转行,java 列转行
  15. USB学习入门(三)------众里寻他千百度(windows)
  16. 用AI生成假员工,8天众筹3万美元,这家创业公司2/3的成员都是假的!
  17. 10004 - Bicoloring
  18. 金额数字3位隔开php,PHP实现人民币数字格式化,每三位加逗号
  19. 『Java』IO--字节流基础
  20. 17世纪初诞生了第一台电子计算机,世界上第一台计算机诞生于多少年?

热门文章

  1. 如何用计算机记英语词汇,计算机常用英语词汇大全
  2. 猿创征文 | 专做药品生产研发的程序员
  3. 【网络文摘】一位36岁程序员的困惑
  4. windows下cmd命令(全面)更新版
  5. 浅谈SVG的两个黑魔法
  6. Android 9 安卓P System-as-root
  7. linux删除文件夹(里面有文件)
  8. Scala高阶函数操作示例详解
  9. Wincc经典版下载
  10. 在Linux系统搭建DNS服务器