^-^ 终于到多线程了!嘿咻。。。嘿咻。。。
线程和多线程:
线程仅仅是一个进程中一条执行路径。通常在应用程序提供上下文中执行。.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。
切忌胡乱设置线程优先级!