C#多线程要点
转自:http://www.cnblogs.com/lovecindywang/archive/2009/12/25/1632014.html
一、前言
(1)开线程的最大数量
每一个线程默认情况下都会占用1M的栈空间(对于普通应用程序来说),在32位Windows平台下可以给一个用户进程使用的程序最大在2G,那么也就是说在程序中使用的线程不能超过2000个,在实际测试中可以发现一般来说开1930左右个线程就会收到内存不足的异常,其实这个数量是绝对够用的,即使复杂的Outlook2007程序一般也只用了50个不到的线程(可以在任务管理器中观察到)。
(2)线程的注意事项
多个线程使用相同资源的话还要考虑资源的锁定以免产生数据的不一致。锁定/事务/并发的概念在数据库中也是非常常见的。二是因为调试困难,特别是一个线程的执行依赖其它线程的执行。三是因为多线程的程序随着环境的变化(处理器/操作系统)可能执行的性能还不一定相同,如果只针对某个环境进行编程可能还不能充分利用多处理器的优势。比如我们对一个任务划分成2个线程并行执行,那么对于四核的处理器来说,划分成4个线程并行执行会不会更合理呢,说实话我也举的这事挺难说的?还有,我们的编程基于.NET框架,而其本质还是使用的是操作系统的线程,操作系统中本来就有很多进程运行着,处理器是大家的处理器,不是专供我们程序使用的,在这么一个鱼龙混杂的环境,我们的程序究竟是不是会表现的如我们预期那样,也很难说。
二、线程基本知识
(1)线程的两种构造函数
不带参数Start():
1 new Thread(() => Add(1, 2)).Start(); 2 static void Add(int i, int j) 3 { 4 Console.WriteLine(i + j); 5 }
带参数Start(),参数为object型的,需要转换:
1 new Thread((date) => Console.WriteLine(((DateTime)date).ToString())).Start(DateTime.Now);
(2)前台线程与后台线程
1 new Thread(() => Console.ReadLine()) { IsBackground = false }.Start();
这是默认情况,可以看到控制台一直在等待用户的输入,按回车后程序结束,如果把IsBackground属性设置为true的话,可以看到程序在运行后马上接结束了,并没有等待线程方法的结束。
(3)优先级属性
优先级高的线程得到运行的次数比优先级低的线程多那么一点,但即使是最低优先级的线程都有很大的机会来执行。所以不知道优先级高低的意义。
(4)线程的中断
1 Thread t2 = new Thread(() => 2 { 3 try 4 { 5 while (true) 6 { 7 Console.WriteLine(Thread.CurrentThread.ThreadState); 8 Thread.Sleep(1000); 9 } 10 } 11 catch (ThreadAbortException abortException) 12 { 13 Console.WriteLine("catch"); 14 Console.WriteLine(Thread.CurrentThread.ThreadState); 15 Console.WriteLine((string)abortException.ExceptionState); 16 } 17 }); 18 t2.Start(); 19 Thread.Sleep(2000); 20 t2.Abort("haha"); 21 Thread.Sleep(100); 22 Console.WriteLine(t2.ThreadState);
注:第11行ThreadAbortException 异常不是必须的,可以不去捕获这个异常。即如下代码也可以正常执行,不会出现异常:
1 Thread t2 = new Thread(() => 2 { 3 //try 4 //{ 5 while (true) 6 { 7 Console.WriteLine(Thread.CurrentThread.ThreadState); 8 Thread.Sleep(1000); 9 } 10 //} 11 //catch (ThreadAbortException abortException) 12 //{ 13 // Console.WriteLine("catch"); 14 // Console.WriteLine(Thread.CurrentThread.ThreadState); 15 // Console.WriteLine((string)abortException.ExceptionState); 16 //} 17 }); 18 t2.Start(); 19 Thread.Sleep(2000); 20 t2.Abort("haha"); 21 Thread.Sleep(100); 22 Console.WriteLine(t2.ThreadState);
(5)线程的Join
用于阻塞调用线,程等Join的线程完成,或传入一个时间,阻塞一定的时间。Join()等Join的线程完成,Join(毫秒)阻塞一定时间。
(6)同时操作静态字段
两个线程都访问了共享的静态字段,可能错开访问可能正巧同步。其实,在静态字段上加上一个ThreadStatic特性就可以解决:
1 [ThreadStatic] 2 static int threadstaticvalue;
注意:但是加了ThreadStatic特性,两个线程却不是共享该字段,相当于有两个不同的静态字段。

浙公网安备 33010602011771号