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();//释放锁 } }); } } }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。