class Program { static void Main(string[] args) { var count = 0; var taskList = new Task[10]; Stopwatch sp = new Stopwatch(); sp.Start(); // 不要意外復制。每個實例都是獨立的。 SpinLock _spinLock = new SpinLock(); for (int i = 0; i < taskList.Length; i++) { taskList[i] = Task.Run(() => { bool _lock = false; for (int j = 0; j < 10_000_000; j++) { _spinLock.Enter(ref _lock); count++; _spinLock.Exit(); _lock = false; } }); } sp.Stop(); Task.WaitAll(taskList); Console.WriteLine($"完成! 耗時:{sp.ElapsedTicks}"); Console.WriteLine($"結果:{count}"); } }
注解
有關如何使用旋轉鎖定的示例, 請參閱如何:使用旋轉鎖進行低級別同步。
自旋鎖可用於葉級鎖, 在這種情況Monitor下, 通過使用、大小或由於垃圾回收壓力而隱含的對象分配的成本非常高。 旋轉鎖定有助於避免阻塞;但是, 如果你預計會有大量的阻塞, 則可能由於旋轉過多而無法使用自旋鎖。 當鎖的粒度較大且數值較大 (例如, 鏈接列表中的每個節點都有一個鎖) 以及鎖保留時間始終極短時, 旋轉可能非常有利。 通常, 在持有自旋鎖時, 應避免使用以下任何操作:
-
堵塞
-
調用自身可能會阻止的任何內容,
-
同時保留多個自旋鎖,
-
進行動態調度的調用 (interface 和虛方法),
-
對任何代碼進行靜態調度調用, 而不是任何代碼, 或
-
分配內存。
SpinLock僅應在確定這樣做后使用才能改善應用程序的性能。 出於性能方面的考慮, 還SpinLock必須注意, 是值類型。 出於此原因, 必須注意不要意外復制SpinLock實例, 因為兩個實例 (原始和副本) 將完全獨立, 這可能會導致應用程序出現錯誤的行為。 如果必須傳遞實例, 則它應按引用而不是按值傳遞。 SpinLock
不要在只讀SpinLock字段中存儲實例。