2015年自己定了个目标就是开始写写博客,所以心血来潮,我也来写写一些基础的东西。
线程,网上大把多资料,自己写也不会有什么新意。不过在自己做过的一些项目中用到很多线程相关的知识,但没有真正的去总结,去归纳的,导致到了用的时候有baidu、google(google被我朝禁了...我觉得是一种悲哀)。好了,下面开始我的线程基础了
1、线程的定义
线程只由相关堆栈(系统栈或用户栈)寄存器和线程控制表TCB组成。它是系统调度的最基本单位。个人的理解是线程相当于开辟一个单元去执行特定的方法过程,就涉及到方法中堆栈的分配,也就是线程堆栈的分配;执行时寄存器的调度使用;它最终由系统控制,按时间片去管理,需要tcb去管理切换等。(仅个人愚见,日后想通了,就另说)。线程有五个主要的基本状态:a、建立,b、就绪,c、运行,d、阻塞,e、消亡
2、.net framework 中的线程的属性
.net framework中提供了System.Threading的命名空间,用于操作线程。
下面是截取MSDN上的关于Thread的属性片段(不完整),如有需要可以去MSDN上看
标注的属性是我接触比较多的。
IsBackground属性标识线程为前台线程还是后台线程。当为true时表示该线程为后台线程,当主线程退出时,线程终止;当为false时为前台线程,要退出主线程,须等待所有前台线程结束有,主线程才完全退出。所以在设计时应该根据实际情况设定线程的IsBackground,默认是false。
IsThreadPool:是否是线程池管理的。不要和IsBackground混为一谈呀(以前想当然了)。
Priority:是线程的优先级别设定,.Net Framework的定义为枚举
1 // 摘要: 2 // 指定 System.Threading.Thread 的调度优先级。 3 [Serializable] 4 [ComVisible(true)] 5 public enum ThreadPriority 6 { 7 // 摘要: 8 // 可以将 System.Threading.Thread 安排在具有任何其他优先级的线程之后。 9 Lowest = 0, 10 // 11 // 摘要: 12 // 可以将 System.Threading.Thread 安排在具有 Normal 优先级的线程之后,在具有 Lowest 优先级的线程之前。 13 BelowNormal = 1, 14 // 15 // 摘要: 16 // 可以将 System.Threading.Thread 安排在具有 AboveNormal 优先级的线程之后,在具有 BelowNormal 优先级的线程之前。默认情况下,线程具有 17 // Normal 优先级。 18 Normal = 2, 19 // 20 // 摘要: 21 // 可以将 System.Threading.Thread 安排在具有 Highest 优先级的线程之后,在具有 Normal 优先级的线程之前。 22 AboveNormal = 3, 23 // 24 // 摘要: 25 // 可以将 System.Threading.Thread 安排在具有任何其他优先级的线程之前。 26 Highest = 4, 27 }
关于线程优先级别,并不是说优先级越高,就先执行哪一个!而是优先级越高表示CPU分配给该线程的时间片越多,优先级别越低cpu为其分配的时间片就越短。
ThreadState:当前线程的状态。貌似也很少用。
3、.Net Framework的线程的方法
当然这个在MSDN上也是有的,这里就不截它了(很多方法,不明觉厉)。
主要说说几个方法吧:
1、Start()---开启线程
2、Sleep(int )----睡,挂起线程,以毫秒记。
3、Join()----阻塞调用线程,直到某个线程终止或经过了指定时间为止。就是抢占cpu优先执行某线程。
4、Interrupt----中断处于 WaitSleepJoin 线程状态的线程。该方法只是中断,会抛出ThreadInterruptedException的异常
5、Abort----终止某线程,在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。
6、SetData和GetNamedDataSlot关于数据槽的,本人表示不明觉厉,很少用到。
举个例子看看先:
1 /// <summary> 2 /// 程序入口 3 /// </summary> 4 /// <param name="args"></param> 5 private static void Main(string[] args) 6 { 7 Thread thread = new Thread(new ThreadStart(ShowTime)); 8 thread.IsBackground = true; 9 thread.Start(); 10 Console.WriteLine(thread.IsThreadPoolThread); 11 Thread.Sleep(10); 12 thread.Interrupt(); 13 //thread.Abort(); 14 // thread.Priority = ThreadPriority.Highest; 15 //thread.Resume(); 16 //thread.Join(); 17 Console.WriteLine("End main:" + DateTime.Now.ToString()); 18 Console.Read(); 19 } 20 /// <summary> 21 /// 显示 22 /// </summary> 23 public static void ShowTime() 24 { 25 26 for (int i = 1; i < 4; i++) 27 { 28 try 29 { 30 Stopwatch stopwatch = new Stopwatch(); 31 stopwatch.Start(); 32 Thread.Sleep(3 * 1000); 33 34 35 stopwatch.Stop(); 36 Console.WriteLine("The {0} time take {1} milliseconds", i, stopwatch.ElapsedMilliseconds); 37 } 38 catch (ThreadInterruptedException interruptedEx) 39 { 40 Console.WriteLine("The {0} time throw interrupt exception: {1}", i, interruptedEx.Message); 41 } 42 catch (ThreadAbortException abortEx) 43 { 44 Console.WriteLine("The {0} time throw abort exception: {1}", i, abortEx.Message); 45 } 46 catch (Exception ex) 47 { 48 Console.WriteLine("The {0} time throw other exception: {1}", i, ex.Message); 49 } 50 } 51 }
运行结果,至于切换(注释部分的结果就不贴了)
4、.Net Framework的线程创建
其实就是有参与无参的构造方式
1 Thread nonThread = new Thread(() => 2 { 3 Console.WriteLine("无参数创建"); 4 }); 5 nonThread.Start(); 6 Thread paramThread = new Thread(new ParameterizedThreadStart((o) => { Console.WriteLine(o); })); 7 paramThread.Start("有参");
OK!今天就写这么多吧!