c#多线程的学习(2)(转)
上一篇 / 下一篇 2007-07-27 16:09:55 / 个人分类:软件开发
假设这样一种情况,两个线程同时维护一个队列,如果一个线程对队列中添加元素,而另外一个线程从队列中取用元素,那么我们称添加元素的线程为生产者,称取用元素的线程为消费者。生产者与消费者问题看起来很简单,但是却是多线程应用中一个必须解决的问题,它涉及到线程之间的同步和通讯问题。
%a"D7w@ S(D0CR0C0
0p0m(^&rm!Y$`0前面说过,每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数。但是多线程环境下,可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生。C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。在C#中,关键字lock定义如下:
%a"D7w@ S(D0CR0C0
0p0m(^&rm!Y$`0前面说过,每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数。但是多线程环境下,可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生。C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。在C#中,关键字lock定义如下:
lock(expression) statement_block |
expression代表你希望跟踪的对象,通常是对象引用。一般地,如果你想保护一个类的实例,你可以使用this;如果你希望保护一个静态变量(如互斥代码段在一个静态方法内部),一般使用类名就可以了。而statement_block就是互斥段的代码,这段代码在一个时刻内只可能被一个线程执行。51Testing软件测试网CU.D[Sy;r'L
下面是一个使用lock关键字的典型例子,我将在注释里向大家说明lock关键字的用法和用途:
下面是一个使用lock关键字的典型例子,我将在注释里向大家说明lock关键字的用法和用途:
//lock.cs A$qp6v1YE_.pE0using System; \h8?mkx0using System.Threading;51Testing软件测试网vI%j[ G 51Testing软件测试网 K/A0c!Jn b wY'YC?Ly)uZ internal class Account 7G^!h-E ~"vk#n#y mm0{51Testing软件测试网1W_IM;S(w int balance;51Testing软件测试网 e*a(b-~"SK'na Random r = new Random();51Testing软件测试网L)E)I*W0^+VkA'F I I1] internal Account(int initial)51Testing软件测试网8z$^U:pM } {51Testing软件测试网ZL8\;y d0NGv$S.Pi balance = initial; ,kw&rf,QctG.x1I(G0 }51Testing软件测试网c4w:z}%]D1O4KM 5t E5v(~R9|.vW?0 internal int Withdraw(int amount) ki#a@+V0 { bO/I$r'}/H(B(Q'o0 if (balance < 0)51Testing软件测试网!Y$x)S"Dml#yZ {51Testing软件测试网6YV2k;A'z file://如果balance小于0则抛出异常 TfnJT1dv3g-i j0 throw new Exception("Negative Balance"); u$I6u}w"MT'DT1i0 }51Testing软件测试网\spr;pU0]] //下面的代码保证在当前线程修改balance的值完成之前 -Sq5WmkH K9R0 //不会有其他线程也执行这段代码来修改balance的值 pi]Y8}{D0 //因此,balance的值是不可能小于0的51Testing软件测试网S~%w(}y)}$|"qW lock (this) ]:^ q Nno d W't6^0 { )[0\,M4RV6Xt*`_(o-v _0 Console.WriteLine("Current Thread:"+Thread.CurrentThread.Name); 7Y8hz9nn)?,T.b0 file://如果没有lock关键字的保护,那么可能在执行完if的条件判断之后51Testing软件测试网&^cC1dd(S file://另外一个线程却执行了balance=balance-amount修改了balance的值 C B u![lE r0 file://而这个修改对这个线程是不可见的,所以可能导致这时if的条件已经不成立了51Testing软件测试网8QO oe1f3h Z)T file://但是,这个线程却继续执行balance=balance-amount,所以导致balance可能小于051Testing软件测试网 U2x|,cf_ bP3S a if (balance >= amount)51Testing软件测试网fc6r#I-y&BM&ui { `d p^YN$QfgL0 Thread.Sleep(5); lY']O2A'clMOt0 balance = balance - amount;51Testing软件测试网 QIQ%j;?{ Y return amount;51Testing软件测试网y6t0r.Jy~ } (bR0^2jc$Z0 else r^-p-m,xO5\0 { 5Aw-q&j |