lock 关键字将语句块标记为 临界区

上传人:小** 文档编号:89125224 上传时间:2019-05-18 格式:DOC 页数:6 大小:19KB
返回 下载 相关 举报
lock 关键字将语句块标记为 临界区_第1页
第1页 / 共6页
lock 关键字将语句块标记为 临界区_第2页
第2页 / 共6页
lock 关键字将语句块标记为 临界区_第3页
第3页 / 共6页
lock 关键字将语句块标记为 临界区_第4页
第4页 / 共6页
lock 关键字将语句块标记为 临界区_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《lock 关键字将语句块标记为 临界区》由会员分享,可在线阅读,更多相关《lock 关键字将语句块标记为 临界区(6页珍藏版)》请在金锄头文库上搜索。

1、lock 关键字将语句块标记为临界区lock关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。此语句的形式如下:ObjectthisLock=newObject();lock(thisLock)/Criticalcodesection备注lock确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。线程处理(C#编程指南)这节讨论了线程处理。lock调用块开始位置的Enter和块结束位置的Exit。通常,应避免锁定public类型,否则实例将超出代码的控制范围。常见的结构lock(t

2、his)、lock(typeof(MyType)和lock(myLock)违反此准则:如果实例可以被公共访问,将出现lock(this)问题。如果MyType可以被公共访问,将出现lock(typeof(MyType)问题。由于进程中使用同一字符串的任何其他代码将共享同一个锁,所以出现lock(myLock)问题。最佳做法是定义private对象来锁定,或privatestatic对象变量来保护所有实例所共有的数据。下例使用线程和lock。只要lock语句存在,语句块就是临界区并且balance永远不会是负数。/statements_lock2.csusingSystem;usingSyste

3、m.Threading;classAccount/这个thisLock必须是线程共享的如果把thisLock放入方法体里面那么thisLock就不是线程共享了,就会抛出异常.privateObjectthisLock=newObject();intbalance;Randomr=newRandom();publicAccount(intinitial)balance=initial;intWithdraw(intamount)/Thisconditionwillneverbetrueunlessthelockstatement/iscommentedout:注释掉if(balance0)thr

4、ownewException(NegativeBalance);/Commentoutthenextlinetoseetheeffectofleavingout/thelockkeyword:lock(thisLock)if(balance=amount)Console.WriteLine(BalancebeforeWithdrawal:+balance);Console.WriteLine(AmounttoWithdraw:-+amount);balance=balance-amount;Console.WriteLine(BalanceafterWithdrawal:+balance);r

5、eturnamount;elsereturn0;/transactionrejectedpublicvoidDoTransactions()for(inti=0;i100;i+)Withdraw(r.Next(1,100);classTeststaticvoidMain()Threadthreads=newThread10;Accountacc=newAccount(1000);for(inti=0;i10;i+)Threadt=newThread(newThreadStart(acc.DoTransactions);threads=t;for(inti=0;i10;i+)threads.St

6、art();使用C#lock同时访问共享数据经常碰到同时需要对某个数据进行操作,或者对某个文件进行读写操作,对于这些操作我们以前往往不能很好的进行处理,自从C#语言中引入了lock这个关键字,以上问题就比较容易予以解决了,下面就是一段简单的代码。publicclassAccessControl()privatestaticobjectprivateObjectLock=newobject();publicstaticAccessResult()lock(privateObjectLock)/数据操作语句=C#多线程中lock的用法在做邮箱接收网关的时候遇到了以下的需求,要求为每一个邮箱开启一个

7、接收线程,从POP3服务器上收取,然后将邮件存放到统一的FTP服务器上,要求邮件按收接顺充从1开始顺充编号。我实现的方法为,为每个邮箱new出实例,然后分别赋给POP3邮箱地址,用户名,密码等参数。这里涉及到一个编号同步的问题,因为每个接收邮件的线程都是自己执行,所以取得编号并且递增这个动作是互斥的。以一个静态变量表示编号如下classEmailInfopublicstaticintCurrentNumber;那在当前线程取得这个步骤为_CurrentNumber=+EmailInfo.CurrentNumber;虽然此为一句,但在计算机运行时却分为多步,如下EmialInfo.Current

8、Number加1-EmailInfo.CurrentNumber返回值给_CurrentNumber,也许线程1执行了EmailInfo.CurrentNumber加1的操作,但还没有取得返回值,此时线程2又执行了EmailInfo.CurrentNumber加1的操作,然后又线程1,线程2取得了返回值就是一样的,这样就失去了按顺序递增的作用。此时查找了网上有关线程同步的方法,其实用lock语句锁住递增的那一段即可。而介绍的相关用法为lock(this)_CurrentNumber=+EmailInfo.CurrentNumber;本以为这样就可以成功,谁知道还是无效,反复查找才发现没弄清楚l

9、ock的用法。因为网上所讲的资料,举的例子比较简单,是直接new出一个对像,然后为对像的一个函数创建了多个线程运行,所以它的同步只要lock住this即它自己就行了。因为此时只有一个实例在运,而我是new出了多个对象,lock住每个自己的实例所以当然无效。所以自然想了一个解决方法,就lock住相同的一个实例就行了。因为我每个邮件接收线程的参数都是不同的,所以还是new出几个实例,但lock的方法改为如下先为EmailInfo加一个静态变量classEmailInfopublicstaticobjectsyncRoot=newobject();publicstaticintCurrentNumber;然后lock改为lock(EmailInfo.syncRoot)_CurrentNumber=+EmailInfo.CurrentNumber;即可实现想要的效果了。写出来之后发现原来是件很简单的事,就是lock住一个大家都共同访问的东东就行了,但这个却搞了我很长时间。究其原因对所查资料没有认真理解,拿来就用,以为什么都懂,其实不然。我想可能有初学者也会犯类似的错误,所以写出来以求共勉。欢迎学习C#或工作中用到C#的朋友与我交流

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 商业/管理/HR > 管理学资料

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号