《CLR via C#》读书笔记-.NET多线程(二)

CLR线程与window线程
目前CLR与Window线程是一一对应关系
专用线程
在.NET中创建多线程有多种方式。一般而言,应该使用CLR线程池中的线程,而不是单独创建一个全新的Thread实例。
以下是多线程基础知识的笔记。
1、Thread的使用需要引用System.Threading.Thread命名空间。
2、Thread的构造器为:

public Thread(
    ParameterizedThreadStart start
)

其中,ParameterizedThreadStart 为一个委托,委托如下:

public delegate void ParameterizedThreadStart(
    object obj
)

其他的构造器可参见MSDN文档。文档如下:MSDN关于Thread的介绍
Thread类创建实例后,Window并不会启动一线程,而是当Thread实例调用start()方法后,window才会创建新的实例。
Thread的属性和方法
1、属性比较简单。
2、方法分为两部分。一部分是本线程方法,start、sleep等方法;另一部分是避免出现多线程竞争时的方法,这些方法以Volatile开头
其中Thread中的join()方法很有意思
MSDN中关于此方法的解释是:

Blocks the calling thread until the thread represented by this instance terminates, while continuing to perform standard COM and SendMessage pumping

即,join方法所在的线程(例如:thread1.join())会阻塞调用join的线程。
例如:本代码摘自MSDN

using System;
using System.Threading;

public class Example
{
   static Thread thread1, thread2;

   public static void Main()
   {
      thread1 = new Thread(ThreadProc);
      thread1.Name = "Thread1";
      thread1.Start();

      thread2 = new Thread(ThreadProc);
      thread2.Name = "Thread2";
      thread2.Start();   
   }

   private static void ThreadProc()
   {
      Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
      if (Thread.CurrentThread.Name == "Thread1" && 
          thread2.ThreadState != ThreadState.Unstarted)
         thread2.Join();

      Thread.Sleep(4000);
      Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
      Console.WriteLine("Thread1: {0}", thread1.ThreadState);
      Console.WriteLine("Thread2: {0}\n", thread2.ThreadState);
   }
}

按照执行顺序。
thread1开始调用ThreadProc方法,在调用过程中使用了 thread2.Join(); 代码,因此当前的线程thread1被阻塞,需要等待thread2执行完毕。当thread2执行完毕后,thread1才会执行剩余的内容。因此,本例的结果如下:

// The example displays output like the following:
//       Current thread: Thread1
//       
//       Current thread: Thread2
//       
//       Current thread: Thread2
//       Thread1: WaitSleepJoin
//       Thread2: Running
//       
//       
//       Current thread: Thread1
//       Thread1: Running
//       Thread2: Stopped

因此,join方法可以解释为:join方法所在的线程拥有最高的执行权限,其他的线程统统阻塞!也正是这种特性,线程自身不能调用join方法,否则会陷入自己等待自己结束的死循环。
以下为MSDN对join方法的解释:

Join is a synchronization method that blocks the calling thread (that is, the thread that calls the method) until the thread whose Join method is called has completed. Use this method to ensure that a thread has been terminated. The caller will block indefinitely if the thread does not terminate. In the following example, the Thread1 thread calls the Join() method of Thread2, which causes Thread1 to block until Thread2 has completed. 

线程调度和优先级
总体一个原则,不要让系统卡顿。因此,耗时很短且需要及时处理的线程,应该使用高优先级;而做相关数据统计等一些需要长时间执行的线程,可以使用低级线程。
改变线程的优先级,可使用Thread.Priority属性,其有7个值,但是只能使用5个。CLR对最高值和最低值进行了限制,禁止应用程序使用最高和最低级,因此线程属性从5选1

    Highest

    AboveNormal

    Normal

    BelowNormal

    Lowest

前台和后台线程
线程分为前台线程和后台线程。
当一个程序的所有的前台线程结束后,CLR会终结后台线程。这个可以用winform程序进行说明。一个winform应用程序中,UI界面为前台程序,而通过CLR线程池创建的线程为后台线程。若程序中有一个单独统计数据的线程正在统计数据,但是当点击界面的关闭按钮时,程序会关闭,所占用的资源会被释放,而统计数据的线程也会被释放。这就是前台线程与后台线程。
前台线程与后台线程可通过Thread的IsBackground进行设定。
总结
在创建线程时,尽量不要使用Thread类,而是使用CLR的线程池。但是若有以下三点需求时,可创建:
1、需要非普通级别的线程时
2、需要线程为前台线程时
3、一个需要长时间运行的线程。线程池在判断是否需要新建额外线程时,逻辑复杂,耗时。
4、启动一个线程,并可能调用abort方法提前终止它时。(这个理由有点牵强,在后面章节可以看到,也可以使用其他方法使一个线程提前结束)

《CLR via C#》25章结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值