版權聲明:本文為博主原創文章,未經博主允許不得轉載。 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();
}
}
}
