多线程编程学习笔记-基础(二)
2023-02-18 15:36:32 时间
接上文 多线程编程学习笔记-基础(一)
五、终止线程 (Abort)
1.代码如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //引入线程 namespace ThreadConsoleApp { class Program { static void Main(string[] args) { Console.WriteLine("开始"); Thread t = new Thread(PrintNumberDely); //启动线程 t.Start(); Thread.Sleep(TimeSpan.FromSeconds(6)); //线程终止 t.Abort(); Console.WriteLine("线程终止"); Console.WriteLine("启动新线程"); t = new Thread(PrintNumber); t.Start(); PrintNumber(); Console.Read(); } static void PrintNumber() { Console.WriteLine("第四个多线程程序开始。。。。Second:" + DateTime.Now.Second); for (int i = 0; i <10; i++) { Console.WriteLine(string.Format("{0}",i)); } } /// <summary> /// 暂停2秒的方法 /// </summary> static void PrintNumberDely() { Console.WriteLine("第一个多线程终止程序开始。。。。"); for (int i = 0; i < 10; i++) { Console.WriteLine(string.Format("Second:{0} == {1}", DateTime.Now.Second, i)); Thread.Sleep(TimeSpan.FromSeconds(2)); } } } }
2.程序执行结果如下
从结果中,可以看出来,程序先启动了子线程的打印数字方法,在运行了6秒之后,调用了abort方法,终止了子线程。但是这个abort是通过注入ThreadAbortException方法,从而使用线程终止,这种方法非常危险,不建议使用。在子线程终止之后,主线程继续运行。
六、检测线程状态(ThreadState)
1.代码如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //引入线程 namespace ThreadConsoleApp { class Program { static void Main(string[] args) { Console.WriteLine("开始"); Thread t = new Thread(PrintNumberStatus); Thread t2 = new Thread(DoNothing); //启动线程 t2.Start(); t.Start(); //显示线程状态 for (int i = 0; i < 10; i++) { Thread.Sleep(TimeSpan.FromMilliseconds(300)); Console.WriteLine(t.ThreadState.ToString()); } Thread.Sleep(TimeSpan.FromSeconds(4)); //线程终止 t.Abort(); Console.WriteLine("线程终止"); Console.WriteLine(string.Format("t线程状态:{0}", t.ThreadState.ToString())); Console.WriteLine(string.Format("t2线程状态:{0}", t2.ThreadState.ToString())); Console.Read(); } static void DoNothing() { Console.WriteLine("第五个多线程程序开始。。。。Second:" + DateTime.Now.Second); Thread.Sleep(TimeSpan.FromSeconds(2)); } /// <summary> /// 暂停2秒的方法 /// </summary> static void PrintNumberStatus() { Console.WriteLine("第五个多线程检测状态程序开始。。。。" + Thread.CurrentThread.ThreadState.ToString()); for (int i = 0; i < 10; i++) { Console.WriteLine(string.Format("Second:{0} == {1}", DateTime.Now.Second, i)); Thread.Sleep(TimeSpan.FromSeconds(2)); } } } }
2.程序执行结果如下
如上图,主线程启动时定义了两个子线程,一个会被终止,另一个会运行至结束。当我们启动了线程之后,t2线程的状态就会变成Running,然后会变成WaitSleepJoin,直到运行结束,变成Stopped。另一个t线程则会打印出数字来,当我们调用了abort方法之后,则t线程的状态就变成了AbortRequested。这充分说明了同步两个线程的复杂性,请不要程序中使用abort来终止线程。
七、线程优先级(Priority)
1.代码如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //引入线程 using System.Diagnostics; namespace ThreadConsoleApp { class Program { static void Main(string[] args) { Console.WriteLine("开始,当前线程的优先级:"+Thread.CurrentThread.Priority); Console.WriteLine("线程运行多核CPU上"); //启动线程 Run(); Thread.Sleep(TimeSpan.FromSeconds(2)); //单核模拟 Console.WriteLine("线程运行单核CPU上"); Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(1); Run(); Console.Read(); } static void Run() { var demo = new ThreadRunDemo(); Thread thread1 = new Thread(demo.CountNumber); thread1.Name = "ThreadOne"; Thread thread2 = new Thread(demo.CountNumber); thread2.Name = "ThreadTwo"; thread2.Priority = ThreadPriority.BelowNormal; Thread thread3 = new Thread(demo.CountNumber); thread3.Name = "ThreadThree"; thread1.Priority = ThreadPriority.Highest; thread2.Priority = ThreadPriority.AboveNormal; thread3.Priority = ThreadPriority.Lowest; thread1.Start(); thread2.Start(); thread3.Start(); Thread.Sleep(2000); demo.Stop(); } } class ThreadRunDemo { private bool isStopped = false; public void Stop() { isStopped = true; } public void CountNumber() { long cnt = 0; while(!isStopped) { cnt++; } Console.WriteLine(string.Format("线程 {0} 的优先级 {1,11} ,一共计算了 {2,13} 数字",
Thread.CurrentThread.Name,Thread.CurrentThread.Priority.ToString(), cnt.ToString("N0"))); } } }
2.程序执行结果如下
从上图的结果中,看出来当在多核CPU上运行多线程程序时,优先级所起到的作用区别不大,以上图的结果来看,最高优先级与最低优先级之间的差别在10%左右。如果在单核CPU上运行多线程程序时,优先级的作用的特别明显,以上图的结果来看,最高优先级与最低优先级之间的差别在100倍以上。
八、前台线程与后台线程
1.代码如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //引入线程 using System.Diagnostics; namespace ThreadConsoleApp { class Program { static void Main(string[] args) { Console.WriteLine("开始,前台线程与后台线程"); var fore = new ThreadBackground(10); var back = new ThreadBackground(20); Thread threadF = new Thread(fore.CountNumber); threadF.Name = "前台线程"; Thread threadB = new Thread(back.CountNumber); threadB.Name = "后台线程"; threadB.IsBackground = true; //启动线程 threadF.Start(); threadB.Start(); //Console.Read(); } } class ThreadBackground { private int cnt ; public ThreadBackground(int count) { cnt = count; } public void CountNumber() { for (int i = 0; i < cnt; i++) { Thread.Sleep(500); Console.WriteLine(string.Format("线程 {0} 打印 {1,11} 数字", Thread.CurrentThread.Name, i.ToString("N0"))); } Console.WriteLine("{0} finished counting.", Thread.CurrentThread.IsBackground ? "Background Thread" : "Foreground Thread"); } } }
2.程序执行结果
根据上面的代码,当程序执行到如上图时,会一闪而过,退出。这是因为前台线程已经执行结束,虽然后台线程没有执行结束,但程序会自动终止后台线程。这就是前台线程与后台线程的区别,进程会等所有的前台线程执行完毕,如果此时只剩下后台线程没有执行完毕,则会直接结束工作。
相关文章
- 优化技术专题-线程间的高性能消息框架-深入浅出Disruptor的使用和原理
- 🏆【Alibaba工具型技术系列】「EasyExcel技术专题」摒除OOM!让你的Excel操作变得更加优雅和安全
- Redis-技术专区-让你彻底会使用“Redis中最陌生且最强大的集合”(ZSET)【前篇】
- 分布式技术专题-分布式协议算法-带你彻底认识Paxos算法、Zab协议和Raft协议的原理和本质
- Redis-技术专区-帮从底层彻底吃透AOF技术原理
- 史上最详细的Windows10系统离线安装.NET Framework 3.5的方法(附离线安装包下载)
- Redis被问到哭?看完这篇,她站起来了……
- Redis-技术专区-帮从底层彻底吃透RDB技术原理
- Mybatis-技术专区-如何清晰的解决出现「多对一模型」和「一对多模型」的问题
- 🏆【JVM技术专区】「难点-核心-遗漏」TLAB内存分配+锁的碰撞(技术串烧)!
- 🏆【Alibaba微服务技术系列】「Dubbo3.0技术专题」回顾Dubbo2.x的技术原理和功能实现及源码分析(温故而知新)
- 【微服务技术专题】Netflix动态化配置服务-微服务配置组件变色龙Archaius
- 🏆【JVM技术专区】「虚拟机专题」JDK/JVM的新储君—GraalVM和Quarkus
- Alibaba-技术专区-RocketMQ 延迟消息实现原理和源码分析
- 【SpringBoot技术专题】「JWT技术专区」SpringSecurity整合JWT授权和认证实现
- Alibaba-技术专区-Dubbo3总体技术体系介绍及技术指南(目录)
- Alibaba-技术专区-Dubbo3总体技术体系介绍及技术指南(序章)
- SpringBoot-技术专区-用正确的姿势如何用外置tomcat配置及运行(Tomcat优化分析)
- 【SpringCloud技术专题】「原生态Fegin」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(下)
- 【SpringCloud技术专题】「原生态Fegin」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(中)