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()

wKioL1TTfK7SMZQdAAAUe6DaUs0457.jpg

 

 

 TheDoJob2()

 

 wKiom1TTe8uTpjWzAABihuIUXBQ711.jpg

 

 =================================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();//释放锁}});}}
}

 wKioL1TTfK7SMZQdAAAUe6DaUs0457.jpg