Monitor類與Lock語句相比,Monitor類的主要優勢是:能夠添加一個等待被鎖定的超時值。c#
缺點:開銷很是大ide
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()this
TheDoJob2()spa
=================================SpinLock(自旋鎖)對象
若是基於對象的的鎖定對象(Monitor)的系統開銷因爲垃圾回收而太高,就能夠使用SpinLock結構。若是有大量的鎖定,且鎖定的時間是很是短,自旋鎖就頗有用。blog
*注意:get
傳送SpinLock實例時要當心。由於SpinLock定義爲結構,把一個變量賦予另外一個變量會建立副本。老是經過引用傳送SpinLock實例。string
例子:it
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();//釋放鎖 } }); } } }