.NET组件程序设计 第8章 多线程和并发管理

来源:互联网 发布:网易贵金属行情软件 编辑:程序博客网 时间:2024/06/05 05:19

^-^ 终于到多线程了!嘿咻。。。嘿咻。。。

 

线程和多线程:

线程仅仅是一个进程中一条执行路径。通常在应用程序提供上下文中执行。.NET中线程为基本执行单元。.NET线程是操作系统底层线程托管代码表示。

例:用户界面在一个线程,应用程序在另一个线程处理用户请求。因为在不同线程上,处理用户请求时,其用户界面任然可以响应。多线程能提高程序吞吐量。

 

.NET Thread类定义在System.Threading中,代表一个托管线程。

ManagedThreadId属性:返回一全进程唯一数值,该ID与操作系统分配原始线程ID无关,只是返回线程对象唯一哈希。

 

创建线程:

创建一新Thread对象,并把它与一个方法关联,这个方法叫线程方法

线程方法一旦返回,线程终止,线程方法签名满足条件:

//无参线程方法委托定义public delegate void ThreadStart();//无参线程方法签名void MethodName();public delegate void ParameterizedThreadStart(object obj);//含参线程方法签名void MethodName(object argument);
private void ShowMessage(){    Thread currentThread = Thread.CurrentThread;    Response.Write("线程:" + currentThread.ManagedThreadId);}ThreadStart threadStart = ShowMessage;//创建一个新线程,用ThreadStart委托实例初始化
//因保证委托实例中只有一个目标方法//Thread workerThread = new Thread(threadStart);
Thread workerThread = new Thread(ShowMessage);
//线程必须显示调用Start()方法,才可真正执行线程方法!
//Start()为非阻塞方法,控制权马上返启动线程,可能是线程启动前某一刻,所以不要做线程已经实际运行的任何假设!workerThread.Start();

 

阻塞线程:

1.挂起和继续线程

Suspend()挂起线程,为一非阻塞调用,控制会立刻返回调用者线程,之后才挂起线程。挂起发生于下一个安全点(代码中一时间点,在这点垃圾回收可安全进行)。挂起线程并非一即时操作,一般避免显示挂起继续线程。

Resume()继续线程。

2.让线程休眠

Sleep()是一个阻塞调用,只有当休眠过后,控制权返回调用线程。

Sleep()使线程处于一特殊线程等待队列里,等待操作系统唤醒。任何调用了Sleep()的线程会自动放弃CUP分配剩余时间。

//强制线程上下文切换(操作系统最高昂的代价之一)Thread.Sleep(0);//线程无限期休眠Thread.Sleep(Timeout.Infinite);

3.在等待过程中消磨时间

SpinWait()类似休眠操作,线程等待规定个数的迭代(怀疑为映射到预定义的一组无操作NOP汇编指令)。不用添加至等待线程队列中,无需线程上下文切换。

int Million = 100000;//在CUP时钟速度不同的机器上,完成时间会不同Thread.SpinWait(Million);

4.加入线程

Join()调用后可以使当前运行线程阻塞直到调用Join()的线程终止才返回。

当指定一超时,Join()会在超时时间到期或线程终止时返回。当超时时间到期线程仍然运行,返回false,线程终结返回true。

static void WaitFor(Thread thread){    //避免陷入等待自己线程终结的死锁    Debug.Assert(Thread.CurrentThread.ManagedThreadId !=     thread.ManagedThreadId);    thread.Join();}

5.中断等待线程

Interrupt()可解除休眠线程(调用Sleep()和Join()的线程)的阻塞,并在解除阻塞的线程中抛出ThreadInterrputedException异常。如未处理该异常,线程会终止。
6.中止线程

Abort()强制性中止一个线程。抛出ThreadAbortException异常,为一特殊异常。不能在挂起的线程上调用Abort()。
ResetAbort()可以阻止.NET在catch语句结束后,再次抛出ThreadAbortException异常。

 

线程状态:

ThreadState枚举定义了.NET管理线程可以有的一组状态。 

 

前台线程和后台线程:

.NET定义了两种托管线程:前台,后台线程。

这两种线程完全相同,除了:只要至少有一个前台线程在运行.NET保持进程处于激活状态,一旦所有前台进程退出,后台进程无法保持.NET进程的激活状态。

默认,新线程是前台线程。

.NET最后一个前台线程终结,.NET会关闭应用程序。之后.NET终止剩下所有后台线程,每个后台线程抛出ThreadAbortException异常。

 

线程优先级和调度:

每个线程都分到一固定时间片断在CPU上运行,并指派一优先级。

T1,T2两线程准备运行,T1优先级高于T2,操作系统挂起T2,让T1先运行。对相同优先级多个线程,各自按CPU时间断运行,再轮换挂起线程。

ThreadPriority枚举提供了5个优先级。新线程优先级默认:ThreadPriority.Normal。

切忌胡乱设置线程优先级!