在.net framework class library中,所有与多线程机制应用相关的类都是放在System.Threading命名空间中的。其中提供Thread类用于创建线程,ThreadPool类用于管理线程池等等,此外还提供解决了线程执行安排,死锁,线程间通讯等实际问题的机制。如果你想在你的应用程序中使用多线程,就必须包含这个类。Thread类有几个至关重要的方法,描述如下:
internal class Account { int balance; Random r = new Random(); internal Account(int initial) { balance = initial; }
internal int Withdraw(int amount) { if (balance < 0) { file://如果balance小于0则抛出异常 throw new Exception("Negative Balance"); } //下面的代码保证在当前线程修改balance的值完成之前 //不会有其他线程也执行这段代码来修改balance的值 //因此,balance的值是不可能小于0的 lock (this) { Console.WriteLine("Current Thread:"+Thread.CurrentThread.Name); file://如果没有lock关键字的保护,那么可能在执行完if的条件判断之后 file://另外一个线程却执行了balance=balance-amount修改了balance的值 file://而这个修改对这个线程是不可见的,所以可能导致这时if的条件已经不成立了 file://但是,这个线程却继续执行balance=balance-amount,所以导致balance可能小于0 if (balance >= amount) { Thread.Sleep(5); balance = balance - amount; return amount; } else { return 0; // transaction rejected } } } internal void DoTransactions() { for (int i = 0; i < 100; i++) Withdraw(r.Next(-50, 100)); } }
internal class Test { static internal Thread[] threads = new Thread[10]; public static void Main() { Account acc = new Account (0); for (int i = 0; i < 10; i++) { Thread t = new Thread(new ThreadStart(acc.DoTransactions)); threads[i] = t; } for (int i = 0; i < 10; i++) threads[i].Name=i.ToString(); for (int i = 0; i < 10; i++) threads[i].Start(); Console.ReadLine(); } }
using System; using System.Collections; using System.Threading;
//这是用来保存信息的数据结构,将作为参数被传递 public class SomeState { public int Cookie; public SomeState(int iCookie) { Cookie = iCookie; } }
public class Alpha { public Hashtable HashCount; public ManualResetEvent eventX; public static int iCount = 0; public static int iMaxCount = 0; public Alpha(int MaxCount) { HashCount = new Hashtable(MaxCount); iMaxCount = MaxCount; }
int iX = 2000; Thread.Sleep(iX); //Interlocked.Increment()操作是一个原子操作,具体请看下面说明 Interlocked.Increment(ref iCount); if (iCount == iMaxCount) { Console.WriteLine(); Console.WriteLine("Setting eventX "); eventX.Set(); } } }
public class SimplePool { public static int Main(string[] args) { Console.WriteLine("Thread Pool Sample:"); bool W2K = false; int MaxCount = 10;//允许线程池中运行最多10个线程 //新建ManualResetEvent对象并且初始化为无信号状态 ManualResetEvent eventX = new ManualResetEvent(false); Console.WriteLine("Queuing {0} items to Thread Pool", MaxCount); Alpha oAlpha = new Alpha(MaxCount); file://创建工作项 //注意初始化oAlpha对象的eventX属性 oAlpha.eventX = eventX; Console.WriteLine("Queue to Thread Pool 0"); try { file://将工作项装入线程池 file://这里要用到Windows 2000以上版本才有的API,所以可能出现NotSupportException异常 ThreadPool.QueueUserWorkItem(new WaitCallback(oAlpha.Beta), new SomeState(0)); W2K = true; } catch (NotSupportedException) { Console.WriteLine("These API's may fail when called on a non-Windows 2000 system."); W2K = false; } if (W2K)//如果当前系统支持ThreadPool的方法. { for (int iItem=1;iItem < MaxCount;iItem++) { //插入队列元素 Console.WriteLine("Queue to Thread Pool {0}", iItem); ThreadPool.QueueUserWorkItem(new WaitCallback(oAlpha.Beta),new SomeState(iItem)); } Console.WriteLine("Waiting for Thread Pool to drain"); file://等待事件的完成,即线程调用ManualResetEvent.Set()方法 eventX.WaitOne(Timeout.Infinite,true); file://WaitOne()方法使调用它的线程等待直到eventX.Set()方法被调用 Console.WriteLine("Thread Pool has been drained (Event fired)"); Console.WriteLine(); Console.WriteLine("Load across threads"); foreach(object o in oAlpha.HashCount.Keys) Console.WriteLine("{0} {1}", o, oAlpha.HashCount[o]); } Console.ReadLine(); return 0;
Thread Pool Sample: Queuing 10 items to Thread Pool Queue to Thread Pool 0 Queue to Thread Pool 1 ... ... Queue to Thread Pool 9 Waiting for Thread Pool to drain 98 0 : HashCount.Count==0, Thread.CurrentThread.GetHashCode()==98 100 1 : HashCount.Count==1, Thread.CurrentThread.GetHashCode()==100 98 2 : ... ... Setting eventX Thread Pool has been drained (Event fired) Load across threads 101 2 100 3 98 4 102 1