c#spinLock使用

来源:互联网 发布:淘宝网宝宝床 编辑:程序博客网 时间:2024/05/16 18:24

一下解释摘自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();        }    }}


0 0
原创粉丝点击