当前位置: 首页 > news >正文

.Net组件程序设计之线程、并发管理(一)

.Net组件程序设计之线程、并发管理(一)

1.线程

  • 线程

  • 线程的创建

  • 线程的阻塞

    • 线程挂起

    • 线程睡眠

    • 加入线程

    • 线程中止

现在几乎所有的应用程序都是多线程的,给用户看来就是一个应用程序界面(应用程序线程),不管什么操作都不会导致界面出现响应慢的情况,这些都是多线程的功劳,有了多线程,可以让应用程序尽最大可能的处理更多的操作,调动很多线程来并行处理请求,这样会使得应用程序有更大的系统吞吐量。

1.线程

1.1线程

线程是什么呢?线程就是进程中的一条执行路径,每个应用程序至少在一个线程上运行。在本篇中将会对线程稍作讲解.

在.NET中,线程是执行的基本单元。在.NET中的线程并非是操作系统中的物理线程,而是对物理线程的托管代码表示。

在.NET System.Threading命名空间下,有个Thread类型的类,它就是代表着托管线程。

1.2线程的创建

 我们直接来看下线程创建的示例:

1
2
3
4
5
6
7
8
9
1      public  class  ThreadingMethodCase
2     {
3          public  static  void  ThreadingMethod()
4         {
5             Thread thread = Thread.CurrentThread;
6              int  threadid = thread.ManagedThreadId;
7             Console.WriteLine(thread.Name +  "ThreadID is "  + threadid);
8         }
9     }
1
2
3
4
1 ThreadStart threadstart =  new  ThreadStart(ThreadingMethodCase.ThreadingMethod);
2 Thread thread =  new  Thread(threadstart);
3 thread.Name =  "SubThread" ;
4 thread.Start();

在.NET中创建一个线程首先需要线程方法,什么叫线程方法?首先线程是一个操作或是一组操作的表示,线程方法就是前面这句话中的【操作】。
这里先看一下Thread类型的构造函数接受了一个ThreadStart类型的无参数委托,这个是好理解的。
线程创建了必须要显示的调用它的Start()函数才能开始执行线程。调用Strat()函数是不会对当前线程造成阻塞的,就是说在调用了之后控制权会立刻的回到当前的线程的客户端中。

1.3线程的阻塞

1.3.1线程挂起

1
2
3
4
5
6
public  sealed  class  Thread
2 {
3     public  void  Suspend();
4     public  void  Resume();
5    ……
6 }

Suspend()方法是挂起线程的执行.

Resume()方法则是释放挂起的线程,让线程继续执行在调用Suspend()方法的时候,是不会造成当前线程阻塞的,在调用后,控制权立即返回的,而且在要被挂起的线程中, 也不是被立即挂起的,而是在执行到一个安全点的时候,才会执行挂机操作的。什么是安全点?举个例子吧,假如要被挂起的线程中 正在执行一个函数的时候,外部被通知命令,要被挂起,这个时候线程是不会被挂起的,当这个函数执行完毕的时候,线程则会被挂起, 假设编辑器是把安全点插设在每个函数的末端的。

.NET中是不推荐我们使用这两个函数的,因为会造成很多方面的不稳定。

1.3.2线程睡眠

 

1
2
3
4
5
6
public  sealed  class  Thread
2 {
3     public  static  void  Sleep( int  millisecondsTimeout);
4     public  static  void  Sleep(TimeSpan timeout);
5    ……
6 }

Sleep()是静态函数,是一个阻塞调用并且使当前线程放弃CPU时间片,就是在休眠指定的时间后,控制权才会返回到调用的线程。

Thread.Sleep(20);//让当前调用线程休眠20毫秒

Thread类还提供了另一种类似于休眠的操作:

1 public static void SpinWait(int iterations);

调用SpinWait()也是会造成当前阻塞的,但是当前线程不会放弃CPU时间片,而是在等待有限的时间(参数设置)后继续执行, 这种函数是在可控的情况下才去这样调用的,比如说当前线程要使用一个资源,而这个资源在被其他线程使用,那么就可以使用 SpinWait()函数,在等待有限的时间后,再去读取资源,如果资源还没被其他线程释放,当前线程也会继续执行,所有这是用于可控的情况下的方法。

1.3.3 加入线程

Thread类的Join()方法可以让一个线程等待另一个线程的终结。

这句定义什么意思呢?说是说不清的,来看一下Thread.Join()示例代码  :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  1      public  class  StudyCase
  2     {
  3          public  void  ThreadingTest()
  4         {
  5             ThreadStart threadstart =  new  ThreadStart(ThreadingMethodCase.ThreadingMethod);
  6             Thread thread =  new  Thread(threadstart);
  7             thread.Name =  "newThread" ;
  8             Thread.CurrentThread.Name =  "CurrentThread" ;
  9              for  ( int  i = 0; i < 5; i++)
10             {
11                  if  (i == 0)
12                 {
13                     thread.Start();
14                     thread.Join();
15                 }
16                 Console.WriteLine(Thread.CurrentThread.Name+ "_" +i.ToString());
17             }
18         }
19 
20     }

 

1
2
3
4
5
6
7
8
9
1      public  class  ThreadingMethodCase
2     {
3          public  static  void  ThreadingMethod()
4         {
5             Thread thread = Thread.CurrentThread;
6              int  threadid = thread.ManagedThreadId;
7             Console.WriteLine(thread.Name +  "ThreadID is "  + threadid);
8         }
9     }

从上图的结果再结合代码看一下,就大概的清楚了Join的意思了,意义就是阻塞当前线程,等待子线程(ThreadingTest函数中的thread变量)执行完毕时,当前线程再执行。

1.3.4线程中止

调用Thread类型提供的Abort()方法可以中止线程的运行,并且被中止的线程会抛出一个ThreadAbortException类型的异常。下面的示例代码会清晰的描述和示例代码结果图。
来看示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  1      public  class  ThreadingMethodCase
  2     {
  3          public  static  void  ThreadingMethodDiv()
  4         {
  5              try
  6             {
  7                  while  ( true )
  8                 {
  9                     Console.WriteLine( "测试子线程中止" );
10                 }
11             }
12              catch  (ThreadAbortException abex)
13             {
14                 Console.WriteLine(Thread.CurrentThread.Name+ "-子线程内部-"  + abex.Message);
15             }
16         }
17     }
18      public  class  StudyCase
19     {
20          public  void  ThreadingTestAbort()
21         {
22             Thread.CurrentThread.Name= "CurrentThread" ;
23             ThreadStart threadstart =  new  ThreadStart(ThreadingMethodCase.ThreadingMethod);
24             Thread thread =  new  Thread(threadstart);
25             thread.Name =  "newThread" ;
26 
27             thread.Start();
28              for  ( int  i = 0; i < 10; i++)
29             {
30                 Console.WriteLine(i.ToString());
31             }
32             thread.Abort();
33             thread.Join();
34 
35             Console.WriteLine( "当前线程" );
36         }
37 
38     }

将在下一章讲解线程同步。

 




     本文转自jinyuan0829 51CTO博客,原文链接:http://blog.51cto.com/jinyuan/1421962,如需转载请自行联系原作者




相关文章:

  • 操作GPIO流驱动生成(W83627为例)
  • 阿里云容器宣布开放支持Kubernetes托管服务
  • admuser让squid账户管理更轻松
  • 【c++】构造函数初始化列表中成员初始化的次序性
  • 如何做好Code Review:思考、方法和实践
  • 人工智能将如何变革视频监控行业?
  • .net实现客户区延伸至至非客户区
  • Windows年底再现图片漏洞攻击!
  • Flash视频播放器flowplayer的使用
  • 彻底卸载Virtual Camera虚拟摄像头
  • 解决 PHPExcel 长数字串显示为科学计数
  • 【HIHOCODER 1403】后缀数组一·重复旋律(后缀数组)
  • C#中如何将DataTable中的数据写入Excel
  • 打印机的一些高级设置
  • Qt4--FormLayout
  • Android框架之Volley
  • Java读取Properties文件的六种方法
  • PaddlePaddle-GitHub的正确打开姿势
  • Python学习之路13-记分
  • socket.io+express实现聊天室的思考(三)
  • Spring-boot 启动时碰到的错误
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 高性能JavaScript阅读简记(三)
  • 后端_MYSQL
  • 记录一下第一次使用npm
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 前端存储 - localStorage
  • 前端相关框架总和
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 微服务入门【系列视频课程】
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • # 安徽锐锋科技IDMS系统简介
  • #每天一道面试题# 什么是MySQL的回表查询
  • $.proxy和$.extend
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (11)MSP430F5529 定时器B
  • (BFS)hdoj2377-Bus Pass
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (二)fiber的基本认识
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (转载)虚函数剖析
  • .aanva
  • .NET 的程序集加载上下文
  • .net 重复调用webservice_Java RMI 远程调用详解,优劣势说明
  • .net/c# memcached 获取所有缓存键(keys)
  • .NET开发不可不知、不可不用的辅助类(一)
  • .NET学习教程二——.net基础定义+VS常用设置
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • @selector(..)警告提示
  • [ 云计算 | AWS 实践 ] Java 如何重命名 Amazon S3 中的文件和文件夹