Monitor类与Lock语句相比,Monitor类的主要优点是:可以添加一个等待被锁定的超时值。
缺点:开销非常大
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace ConsoleApplication2 {class Program{static void Main(string[] args){ShareClass sc = new ShareClass();Job j=new Job (sc);Task[] ts=new Task[20];for (int i = 0; i < 20; i++){ts[i] = new Task(j.TheDoJob2);ts[i].Start();}for (int i = 0; i < 20; i++){ts[i].Wait();}Console.WriteLine(sc.state);Console.ReadKey();}}class ShareClass{public int state { get; set; }}class Job{ShareClass sc { get; set; }private object obj = new object();public Job(ShareClass s){sc = s;}//==========普通的Monitor类public void TheDoJob(){//锁定Monitor.Enter(obj);try{for (int i = 0; i < 10000; i++){sc.state++;}}catch { }finally{//如果抛出异常也会就出锁//释放锁Monitor.Exit(obj); }}//===========给Monitor类设置超时时间public void TheDoJob2(){bool yesno=false;//锁定Monitor.TryEnter(obj, 100, ref yesno);if (yesno){for (int i = 0; i < 10000; i++){sc.state++;}Console.WriteLine("yes");//释放锁Monitor.Exit(obj);}else{//如果超时会执行下面代码Console.WriteLine("no");}}} }
TheDoJob()
TheDoJob2()
=================================SpinLock(自旋锁)
如果基于对象的的锁定对象(Monitor)的系统开销由于垃圾回收而过高,就可以使用SpinLock结构。如果有大量的锁定,且锁定的时间是非常短,自旋锁就很有用。
*注意:
传送SpinLock实例时要小心。因为SpinLock定义为结构,把一个变量赋予另一个变量会创建副本。总是通过引用传送SpinLock实例。
例子:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace ConsoleApplication5 {class Program{static void Main(string[] args){ShareClass sc = new ShareClass();Job j = new Job(sc);int sum = 20;Task[] t = new Task[sum];//开启20个任务for (int i = 0; i < sum; i++){t[i] = new Task(j.JobStart);t[i].Start();}//等待20个任务全部结束for (int i = 0; i < sum; i++){t[i].Wait();}Console.WriteLine(sc.State);Console.ReadKey();}}//共享类class ShareClass{public int State { get; set; }}class Job{//声明一个自旋锁,自旋锁是一个结构(不能为属性)private SpinLock sl;//共享类private ShareClass sc;public Job(ShareClass _sc){this.sc = _sc;this.sl = new SpinLock();}public void JobStart(){//并行循环Parallel.For(0, 10000, i =>{bool spinToken = false;sl.Enter(ref spinToken);//锁定try{sc.State++;}finally{if (spinToken)sl.Exit();//释放锁}});}} }
转载于:https://blog.51cto.com/962410314/1612134