Monitor类与Lock语句相比,Monitor类的主要优点是:可以添加一个等待被锁定的超时值。

缺点:开销非常大

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Threading;namespaceConsoleApplication2{classProgram{staticvoidMain(string[]args){ShareClasssc=newShareClass();Jobj=newJob(sc);Task[]ts=newTask[20];for(inti=0;i<20;i++){ts[i]=newTask(j.TheDoJob2);ts[i].Start();}for(inti=0;i<20;i++){ts[i].Wait();}Console.WriteLine(sc.state);Console.ReadKey();}}classShareClass{publicintstate{get;set;}}classJob{ShareClasssc{get;set;}privateobjectobj=newobject();publicJob(ShareClasss){sc=s;}//==========普通的Monitor类publicvoidTheDoJob(){//锁定Monitor.Enter(obj);try{for(inti=0;i<10000;i++){sc.state++;}}catch{}finally{//如果抛出异常也会就出锁//释放锁Monitor.Exit(obj);}}//===========给Monitor类设置超时时间publicvoidTheDoJob2(){boolyesno=false;//锁定Monitor.TryEnter(obj,100,refyesno);if(yesno){for(inti=0;i<10000;i++){sc.state++;}Console.WriteLine("yes");//释放锁Monitor.Exit(obj);}else{//如果超时会执行下面代码Console.WriteLine("no");}}}}

TheDoJob()

TheDoJob2()

=================================SpinLock(自旋锁)

如果基于对象的的锁定对象(Monitor)的系统开销由于垃圾回收而过高,就可以使用SpinLock结构。如果有大量的锁定,且锁定的时间是非常短,自旋锁就很有用。

*注意:

传送SpinLock实例时要小心。因为SpinLock定义为结构,把一个变量赋予另一个变量会创建副本。总是通过引用传送SpinLock实例。

例子:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Threading;namespaceConsoleApplication5{classProgram{staticvoidMain(string[]args){ShareClasssc=newShareClass();Jobj=newJob(sc);intsum=20;Task[]t=newTask[sum];//开启20个任务for(inti=0;i<sum;i++){t[i]=newTask(j.JobStart);t[i].Start();}//等待20个任务全部结束for(inti=0;i<sum;i++){t[i].Wait();}Console.WriteLine(sc.State);Console.ReadKey();}}//共享类classShareClass{publicintState{get;set;}}classJob{//声明一个自旋锁,自旋锁是一个结构(不能为属性)privateSpinLocksl;//共享类privateShareClasssc;publicJob(ShareClass_sc){this.sc=_sc;this.sl=newSpinLock();}publicvoidJobStart(){//并行循环Parallel.For(0,10000,i=>{boolspinToken=false;sl.Enter(refspinToken);//锁定try{sc.State++;}finally{if(spinToken)sl.Exit();//释放锁}});}}}