以ThreadStart方式实现多线程
3.1 使用ThreadStart委托
这里先以一个例子体现一下多线程带来的好处,首先在Message类中建立一个方法ShowMessage(),里面显示了当前运行线程的Id,并使用Thread.Sleep(int ) 方法模拟部分工作。在main()中通过ThreadStart委托绑定Message对象的ShowMessage()方法,然后通过Thread.Start()执行异步方法。
1 public class Message 2 { 3 public void ShowMessage() 4 { 5 string message = string.Format("Async threadId is :{0}", 6 Thread.CurrentThread.ManagedThreadId); 7 Console.WriteLine(message); 8 9 for (int n = 0; n < 10; n++)10 {11 Thread.Sleep(300); 12 Console.WriteLine("The number is:" + n.ToString()); 13 }14 }15 }16 17 class Program18 {19 static void Main(string[] args)20 {21 Console.WriteLine("Main threadId is:"+22 Thread.CurrentThread.ManagedThreadId);23 Message message=new Message();24 Thread thread = new Thread(new ThreadStart(message.ShowMessage));25 thread.Start();26 Console.WriteLine("Do something ..........!");27 Console.WriteLine("Main thread working is complete!");28 29 }30 }
请注意运行结果,在调用Thread.Start()方法后,系统以异步方式运行Message.ShowMessage(),而主线程的操作是继续执行的,在Message.ShowMessage()完成前,主线程已完成所有的操作。
3.2 使用ParameterizedThreadStart委托
ParameterizedThreadStart委托与ThreadStart委托非常相似,但ParameterizedThreadStart委托是面向带参数方法的。注意ParameterizedThreadStart 对应方法的参数为object,此参数可以为一个值对象,也可以为一个自定义对象。
1 public class Person 2 { 3 public string Name 4 { 5 get; 6 set; 7 } 8 public int Age 9 {10 get;11 set;12 }13 }14 15 public class Message16 {17 public void ShowMessage(object person)18 {19 if (person != null)20 {21 Person _person = (Person)person;22 string message = string.Format("\n{0}'s age is {1}!\nAsync threadId is:{2}",23 _person.Name,_person.Age,Thread.CurrentThread.ManagedThreadId);24 Console.WriteLine(message);25 }26 for (int n = 0; n < 10; n++)27 {28 Thread.Sleep(300); 29 Console.WriteLine("The number is:" + n.ToString()); 30 }31 }32 }33 34 class Program35 {36 static void Main(string[] args)37 { 38 Console.WriteLine("Main threadId is:"+Thread.CurrentThread.ManagedThreadId);39 40 Message message=new Message();41 //绑定带参数的异步方法42 Thread thread = new Thread(new ParameterizedThreadStart(message.ShowMessage));43 Person person = new Person();44 person.Name = "Jack";45 person.Age = 21;46 thread.Start(person); //启动异步线程 47 48 Console.WriteLine("Do something ..........!");49 Console.WriteLine("Main thread working is complete!");50 51 }52 }
运行结果:
3.3 前台线程与后台线程
注意以上两个例子都没有使用Console.ReadKey(),但系统依然会等待异步线程完成后才会结束。这是因为使用Thread.Start()启动的线程默认为前台线程,而系统必须等待所有前台线程运行结束后,应用程序域才会自动卸载。
在第二节曾经介绍过线程Thread有一个属性IsBackground,通过把此属性设置为true,就可以把线程设置为后台线程!这时应用程序域将在主线程完成时就被卸载,而不会等待异步线程的运行。
3.4 挂起线程
为了等待其他后台线程完成后再结束主线程,就可以使用Thread.Sleep()方法。
1 public class Message 2 { 3 public void ShowMessage() 4 { 5 string message = string.Format("\nAsync threadId is:{0}", 6 Thread.CurrentThread.ManagedThreadId); 7 Console.WriteLine(message); 8 for (int n = 0; n < 10; n++) 9 {10 Thread.Sleep(300);11 Console.WriteLine("The number is:" + n.ToString());12 }13 }14 }15 16 class Program17 {18 static void Main(string[] args)19 { 20 Console.WriteLine("Main threadId is:"+21 Thread.CurrentThread.ManagedThreadId);22 23 Message message=new Message();24 Thread thread = new Thread(new ThreadStart(message.ShowMessage));25 thread.IsBackground = true;26 thread.Start();27 28 Console.WriteLine("Do something ..........!");29 Console.WriteLine("Main thread working is complete!");30 Console.WriteLine("Main thread sleep!");31 Thread.Sleep(5000);32 }33 }
运行结果如下,此时应用程序域将在主线程运行5秒后自动结束
但系统无法预知异步线程需要运行的时间,所以用通过Thread.Sleep(int)阻塞主线程并不是一个好的解决方法。有见及此,.NET专门为等待异步线程完成开发了另一个方法thread.Join()。把上面例子中的最后一行Thread.Sleep(5000)修改为 thread.Join() 就能保证主线程在异步线程thread运行结束后才会终止。
3.5 Suspend 与 Resume (慎用)
Thread.Suspend()与 Thread.Resume()是在Framework1.0 就已经存在的老方法了,它们分别可以挂起、恢复线程。但在Framework2.0中就已经明确排斥这两个方法。这是因为一旦某个线程占用了已有的资源,再使用Suspend()使线程长期处于挂起状态,当在其他线程调用这些资源的时候就会引起死锁!所以在没有必要的情况下应该避免使用这两个方法。
3.6 终止线程
若想终止正在运行的线程,可以使用Abort()方法。在使用Abort()的时候,将引发一个特殊异常 ThreadAbortException 。
若想在线程终止前恢复线程的执行,可以在捕获异常后 ,在catch(ThreadAbortException ex){...} 中调用Thread.ResetAbort()取消终止。
而使用Thread.Join()可以保证应用程序域等待异步线程结束后才终止运行。
1 static void Main(string[] args) 2 { 3 Console.WriteLine("Main threadId is:" + 4 Thread.CurrentThread.ManagedThreadId); 5 6 Thread thread = new Thread(new ThreadStart(AsyncThread)); 7 thread.IsBackground = true; 8 thread.Start(); 9 thread.Join();10 11 } 12 13 //以异步方式调用14 static void AsyncThread()15 {16 try17 {18 string message = string.Format("\nAsync threadId is:{0}",19 Thread.CurrentThread.ManagedThreadId);20 Console.WriteLine(message);21 22 for (int n = 0; n < 10; n++)23 {24 //当n等于4时,终止线程25 if (n >= 4)26 {27 Thread.CurrentThread.Abort(n);28 }29 Thread.Sleep(300);30 Console.WriteLine("The number is:" + n.ToString());31 }32 }33 catch (ThreadAbortException ex)34 {35 //输出终止线程时n的值36 if (ex.ExceptionState != null)37 Console.WriteLine(string.Format("Thread abort when the number is: {0}!", 38 ex.ExceptionState.ToString()));39 40 //取消终止,继续执行线程41 Thread.ResetAbort();42 Console.WriteLine("Thread ResetAbort!");43 }44 45 //线程结束46 Console.WriteLine("Thread Close!");47 }
运行结果如下
转载于:https://www.cnblogs.com/meilibao/archive/2012/10/16/2725736.html
以ThreadStart方式实现多线程相关推荐
- java的多线程实现方式_java 多线程实现方式
本文主要是对java 多线程知识的总结,做个记录,温故知新. 多线程有三种实现方式,具体如下. 继承Thread类创建线程类 重写run方法,完成线程需要做的任务. 创建实例 调用start()启动线 ...
- 操作系统(十二)线程的实现方式、多线程模型
2.1.6 线程的实现方式.多线程模型 目录 2.1.6 线程的实现方式.多线程模型 2.1.6.1 线程的实现方式 2.1.6.2 多线程模型 2.1.6.1 线程的实现方式 线程已在许多系统中 ...
- java 多线程两种方式_JAVA多线程实现的两种方式
java多线程实现方式主要有两种:继承Thread类.实现Runnable接口 1.继承Thread类实现多线程 继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了 ...
- 线程实现的方式、多线程模型
文章目录 前言 一.用户级线程 二.内核级线程 三.组合实现 四.多线程模型 1.多对一模型 2.一对一模型 3.多对多模型 前言 参考文章:https://blog.csdn.net/qq_4060 ...
- java多线程的实现方式_JAVA多线程实现的三种方式
最近在做代码优化时学习和研究了下JAVA多线程的使用,看了菜鸟们的见解后做了下总结. 1.JAVA多线程实现方式 JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用E ...
- Lambda方式创建多线程
Lambda方式创建多线程 一.Lambda表达式的标准格式 Lamdba创建线程,是对匿名内部类创建多线程的简化 由三部分组成: a.一些参数b.一个箭头c.一段代码 格式: (参数列表)-> ...
- 多线程初探:三种方式创建多线程详细示例
多线程即在同一时间,可以做多件事情. 创建多线程有3种方式,分别是继承线程类,实现Runnable接口,匿名类 一:线程概念 首先要理解进程(Processor)和线程(Thread)的区别 进程:启 ...
- java多线程的实现方式_Java 多线程(一)——多线程的实现方式
一.前言 Java 异常的处理方式与自定义异常 我们已经讲完了,从今天开始我们来学习多线程. 二.与多线程相关的概念 2.1.并发与并行并发:指两个或多个事件在同一个时间段内发生,具体如下图所示: 并 ...
- java实现线程的方式_java多线程实现的四种方式
java多线程实现的四种方式1.继承Thread类,重写run方法(其实Thread类本身也实现了Runnable接口) 2.实现Runnable接口,重写run方法 3.实现Callable接口,重 ...
最新文章
- 组会PPT202006220717《双研究步骤的螺旋波等离子体放电结果分析》
- 直播 | WWW 2021:用先验知识指导BERT注意力机制的语义文本匹配
- bash: gitbook: command not found
- 聊聊JVM(六)理解JVM的safepoint
- python数据库模糊查询_Python操作mongodb数据库进行模糊查询操作示例
- count(1),count(*),count(主键) 性能对比及辟谣
- lombok之@Slf4j注解
- Shiro学习总结(3)——Apache Shiro身份认证
- java编译可执行文件_Java编译器完成但没有创建可执行文件?
- jdbctemplate mysql 配置_Spring Boot 初级入门教程(十四) —— 配置 MySQL 数据库和使用 JdbcTemplate 测试...
- 零基础学python用哪本书好-零基础学习python推荐几本书?
- EditText以及登录UI实现
- echarts改变颜色属性的demo
- 【GD32L233C-START】11、GD32 ISP软件还不支持GD32L233
- JDBC下载,使用,访问数据库
- php image函数,操作压缩图片时,png图片压缩后整个图片变黑
- 数据库连接池种类、C3P0数据库连接池、德鲁伊数据库连接池
- 方法的重写和重载,接口和抽象类区别
- Visualization of Detail Point Set by Local Algebraic Sphere Fitting
- JASS代码翻译更新(第十篇)