版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/u011915028/article/details/53011811
一下解釋摘自msdn msdn鏈接
自旋鎖可用於葉級鎖定,此時在大小方面或由於垃圾回收壓力,使用 Monitor 所隱含的對象分配消耗過多。自旋鎖非常有助於避免阻塞,但是如果預期有大量阻塞,由於旋轉過多,您可能不應該使用自旋鎖。當鎖是細粒度的並且數量巨大(例如鏈接的列表中每個節點一個鎖)時以及鎖保持時間總是非常短時,旋轉可能非常有幫助。通常,在保持一個旋鎖時,應避免任何這些操作:
-
阻塞,
-
調用本身可能阻塞的任何內容,
-
一次保持多個自旋鎖,
-
進行動態調度的調用(接口和虛方法)
-
在某一方不擁有的任何代碼中進行動態調度的調用,或
-
分配內存。
SpinLock 僅當您確定這樣做可以改進應用程序的性能之后才能使用。另外,務必請注意 SpinLock 是一個值類型(出於性能原因)。因此,您必須非常小心,不要意外復制了 SpinLock 實例,因為兩個實例(原件和副本)之間完全獨立,這可能會導致應用程序出現錯誤行為。如果必須傳遞 SpinLock 實例,則應該通過引用而不是通過值傳遞。
不要將 SpinLock 實例存儲在只讀字段中。
實例代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; namespace spinLock { class Program { //得到當前線程的handler [DllImport("kernel32.dll")] static extern IntPtr GetCurrentThread(); //創建自旋鎖 private static SpinLock spin = new SpinLock(); public static void doWork1() { bool lockTaken = false; try { //申請獲取鎖 spin.Enter(ref lockTaken); //下面為臨界區 for(int i=0;i<10;++i) { Console.WriteLine(2); } } finally { //工作完畢,或者發生異常時,檢測一下當前線程是否占有鎖,如果咱有了鎖釋放它 //以避免出現死鎖的情況 if (lockTaken) spin.Exit(); } } public static void doWork2() { bool lockTaken = false; try { spin.Enter(ref lockTaken); for (int i = 0; i < 10; ++i) { Console.WriteLine(1); } } finally { if (lockTaken) spin.Exit(); } } static void Main(string[] args) { Thread[] t = new Thread[2]; t[0] = new Thread(new ThreadStart(doWork1)); t[1] = new Thread(new ThreadStart(doWork2)); t[0].Start(); t[1].Start(); t[0].Join(); t[1].Join(); Console.ReadKey(); } } }