原子操作、自旋锁

   private static int a = 0;
        static void Main(string[] args)
        {
            // 原子操作
            var b = 0;
            b = Interlocked.Increment(ref a); // 自增1

            b = Interlocked.Decrement(ref a);// 自减

            b = Interlocked.Add(ref a,  b); // 返回a 加b的值

            Interlocked.Exchange(ref a, 1); // 返回交换后的值,

            Interlocked.CompareExchange(ref a, 2, 0);  // 变量a的值如果等于0,则将2 赋值给a ,并且然后返回原始值(修改之前的值)

  

 

 

 

 

自旋锁:

   线程会不断的循环获取锁,直到锁被释放。  不公平的锁,没办法保证等待最长时间的线程获取锁,假如有8个线程,都在不断循环获取锁,总有线程‘’点子背‘’,获取不到锁(线程饥饿)

  优点:自旋锁 不会使线程的状态切换,减小上下文的切换,上下文的切换 会消耗性能

  public static class Sample
    {
        private static int _lock = 0;
        private static int _CounterA = 0;
        private static int _Counterb = 0;

        private static SpinLock _locker = new SpinLock();

        public static void IncrementCounter()
        {
            var spinwait = new SpinWait();
            while (Interlocked.Exchange(ref _lock, 1) != 0)
            {
                // 汇编指令,pause
                Thread.SpinWait(1);
                // 或者

                spinwait.SpinOnce();
                // 一定次数内,核心数大于1。会调用   Thread.SpinWait
                // 超过一定的次数,核心数等于1,会交替调用
                // 【thread.sleep(0)[windows中的sleep函数,实际上调用sleepex的一个系统函数]和thread.yied[他是调用一个叫switchtothread的函数],
                // 前者在整个核心中切换,后者只在自己核心切换,前者赋值0的意义是立刻放在待执行的队列里】
                // 交替使用告诉操作系统切换到其他线程
                //在超过一定的次数,thread.sleep(1) 会休眠1毫秒,减少性能消耗
            }

            //锁保护区
            {
                _CounterA++;
                _Counterb++;
            }
            // 释放锁
            Interlocked.Exchange(ref _lock, 0);


            // 以下方式可替换上面,直接使用封装好的类,直接实现了自旋锁
            {
                var lockToken = false;
                try
                {
                    _locker.Enter(ref lockToken);
                    // 锁保护区
                    {
                        _CounterA++;
                        _Counterb++;
                    }
                }
                finally
                {
                    // 释放锁
                    if (lockToken)
                    {
                        _locker.Exit();
                    }
                }
            }


        }
    }

  

 

posted @ 2020-07-31 08:02  谁说程序猿很猥琐  阅读(446)  评论(0编辑  收藏  举报