始创于2000年 股票代码:831685
咨询热线:0371-60135900 注册有礼 登录
  • 挂牌上市企业
  • 60秒人工响应
  • 99.99%连通率
  • 7*24h人工
  • 故障100倍补偿
您的位置: 网站首页 > 帮助中心>文章内容

.NET中线程的生命周期

发布时间:  2012/9/11 17:06:09

让一个线程进入睡眠状态

当我们创建一个线程后,我们需要调用线程对象的Start()方法来调度那个线程。在这时,CLR将会为作为构造函数参数传递给线程对象的方法地址分配一个时间片。一旦线程开始执行,它就可以在操作系统处理其他线程时回到睡眠状态或者退出状态。我们可以使用线程类的Sleep()方法让一个线程进入睡眠状态。如果你正在等待一个资源并且你想在稍后继续尝试访问这个资源时,Sleep()方法是很重要的。举个例子,假设你的程序由于无法访问需要的资源而导致其不能继续执行时,你可能想要在几毫秒之后尝试继续访问资源,在这种情况下让线程在再次尝试访问资源之前睡眠一段时间是一个很好的方式。

Sleep()方法有两种重载方式。第一种重载方法有一个整型参数,并会按照指定的毫秒时间暂停线程执行。例如,如果你向线程传递值100,那么线程将会暂停100毫秒。这个方法将会让线程进入WaitSleepJoin状态。让我们看一个例子,thread_sleep2.cs:

  1. /*************************************  
  2. /* Copyright (c) 2012 Daniel Dong  
  3. *  
  4. * Author:Daniel Dong  
  5. * Blog: www.cnblogs.com/danielWise  
  6. * Email: guofoo@163.com  
  7. *  
  8. */ 
  9. using System;  
  10. using System.Collections.Generic;  
  11. using System.Text;  
  12. using System.Threading;  
  13. namespace SimpleThread  
  14. {  
  15. public class ThreadSleep  
  16. {  
  17. public static Thread worker;  
  18. public static Thread worker2;  
  19. public static void Main()  
  20. {  
  21. Console.WriteLine("Entering the void Main!");  
  22. worker = new Thread(new ThreadStart(Counter));  
  23. worker2 = new Thread(new ThreadStart(Counter2));  
  24. //Make the worker2 Object as highest priority  
  25. worker2.Priority = ThreadPriority.Highest;  
  26. worker.Start();  
  27. worker2.Start();  
  28. Console.WriteLine("Exiting the void Main!");  
  29. Console.ReadLine();  
  30. }  
  31.  public static void Counter()  
  32. {  
  33. Console.WriteLine("Entering Counter");  
  34. for (int i = 1; i <50; i++)  
  35. {  
  36. Console.Write(i + " ");  
  37. if (i == 10)  
  38. {  
  39. Console.WriteLine();  
  40. Thread.Sleep(1000);  
  41. }  
  42. }  
  43. Console.WriteLine("Exiting Counter");  
  44. }  
  45. public static void Counter2()  
  46. {  
  47. Console.WriteLine("Entering Counter2");  
  48. for (int i = 51; i <100; i++)  
  49. {  
  50. Console.Write(i + " ");  
  51. if (i == 70)  
  52. {  
  53. Console.WriteLine();  
  54. Thread.Sleep(5000);  
  55.  }  
  56. }  
  57. Console.WriteLine("Exiting Counter2");  
  58. }  
  59. }  

 

Counter()方法从1到50计数,当到达10以后睡眠1000毫秒。Counter2()方法从51~100计数,当到达70时睡眠5000毫秒。下面是输出结果:

注:以上是在多核CPU下运行的结果,单核CPU 执行情况可能与上图有所出入。

第二种重载方法有一个TimeSpan类型参数,当前线程会按照TimeSpan的值暂停一段时间。TimeSpan是System命名空间中的一个类。TimeSpan有一些很有用的属性并会返回基于时钟时间间隔。

我们可以使用FromSeconds()和FromMinutes()来确定睡眠时间。下面是一个例子,thread_sleep3.cs:

 

  1. public static void Counter()  
  2. {  
  3. Console.WriteLine("Entering Counter");  
  4. for (int i = 1; i <50; i++)  
  5. {  
  6. Console.Write(i + " ");  
  7. if (i == 10)  
  8. {  
  9. Console.WriteLine();  
  10. Thread.Sleep(TimeSpan.FromSeconds(1));  
  11.  }  
  12. }  
  13. Console.WriteLine("Exiting Counter");  
  14. }  
  15. public static void Counter2()  
  16. {  
  17. Console.WriteLine("Entering Counter2");  
  18. for (int i = 51; i <100; i++)  
  19. {  
  20.  Console.Write(i + " ");  
  21. if (i == 70)  
  22. {  
  23. Console.WriteLine();  
  24. Thread.Sleep(TimeSpan.FromSeconds(5));  
  25. }  
  26. }  
  27. Console.WriteLine("Exiting Counter2");  

 

输出结果与thread_sleep2类似。

中断一个线程

当让一个线程睡眠时,它实际会进入WaitSleepJoin状态。如果线程处理睡眠状态,那么在它超时退出之前唯一可以唤醒线程的方式是使用Interrupt()方法。Interrupt()方法将让线程回到调度队列中去。让我们看一个例子,thread_interrupt.cs:

 

  1. /*************************************  
  2. /* Copyright (c) 2012 Daniel Dong  
  3. *  
  4. * Author:Daniel Dong  
  5. * Blog: www.cnblogs.com/danielWise  
  6. * Email: guofoo@163.com  
  7. *  
  8. */ 
  9. using System;  
  10. using System.Collections.Generic;  
  11. using System.Text;  
  12. using System.Threading;  
  13.  namespace SimpleThread  
  14. {  
  15. public class Interrupt  
  16. {  
  17. public static Thread sleeper;  
  18. public static Thread worker;  
  19. public static void Main()  
  20. {  
  21. Console.WriteLine("Entering the void Main!");  
  22. sleeper = new Thread(new ThreadStart(SleepingThread));  
  23. worker = new Thread(new ThreadStart(AwakeThread));  
  24. sleeper.Start();  
  25. worker.Start();  
  26. Console.WriteLine("Exiting the void Main!");  
  27. Console.ReadLine();  
  28. }  
  29.  public static void SleepingThread()  
  30. {  
  31. for (int i = 1; i <50; i++)  
  32. {  
  33. Console.Write(i + " ");  
  34. if (i == 10 || i == 20 || i == 30)  
  35. {  
  36. Console.WriteLine("Going to sleep at: " + i);  
  37. try 
  38. {  
  39. Thread.Sleep(20);  
  40. }  
  41. catch (ThreadInterruptedException ex)  
  42. {  
  43. Console.WriteLine(ex.Message);  
  44. }  
  45.  }  
  46. }  
  47. }  
  48. public static void AwakeThread()  
  49. {  
  50. for (int i = 51; i <100; i++)  
  51. {  
  52. Console.Write(i + " ");  
  53. if (sleeper.ThreadState == ThreadState.WaitSleepJoin)  
  54. {  
  55. Console.WriteLine("Interrupting the sleeping thread.");  
  56. sleeper.Interrupt();  
  57. }  
  58. }  
  59. }  
  60. }  

 

在上面的例子中,当计数器的值为10, 20 和 30 时第一个线程会睡眠。第二个线程会检查第一个线程是否已经进入睡眠状态。如果是的话,它将中断第一个线程并使它回到调度队列中去。Interrupt()方法是让睡眠线程重新醒来的最好方式,当线程等待的资源可用且你想让线程继续运行时你可以使用这个方法。输出结果与下面显示的类似:


本文出自:亿恩科技【www.enkj.com】

服务器租用/服务器托管中国五强!虚拟主机域名注册顶级提供商!15年品质保障!--亿恩科技[ENKJ.COM]

  • 您可能在找
  • 亿恩北京公司:
  • 经营性ICP/ISP证:京B2-20150015
  • 亿恩郑州公司:
  • 经营性ICP/ISP/IDC证:豫B1.B2-20060070
  • 亿恩南昌公司:
  • 经营性ICP/ISP证:赣B2-20080012
  • 服务器/云主机 24小时售后服务电话:0371-60135900
  • 虚拟主机/智能建站 24小时售后服务电话:0371-60135900
  • 专注服务器托管17年
    扫扫关注-微信公众号
    0371-60135900
    Copyright© 1999-2019 ENKJ All Rights Reserved 亿恩科技 版权所有  地址:郑州市高新区翠竹街1号总部企业基地亿恩大厦  法律顾问:河南亚太人律师事务所郝建锋、杜慧月律师   京公网安备41019702002023号
      0
     
     
     
     

    0371-60135900
    7*24小时客服服务热线