zoukankan      html  css  js  c++  java
  • SpinLock(自旋锁)

    SpinLock(自旋锁)

    SpinLock 结构是一个低级别的互斥同步基元,它在等待获取锁时进行旋转。 在多核计算机上,当等待时间预计较短且极少出现争用情况时,SpinLock 的性能将高于其他类型的锁。 不过,仅在通过分析确定 System.Threading.Monitor 方法或 Interlocked 方法显著降低了程序的性能时使用 SpinLock。

    System.Threading.SpinLock 是一个低级别的互斥锁,可用于等待时间非常短的场合SpinLock 不是可重入的。 在线程进入锁之后,它必须先正确地退出锁,然后才能再次进入锁。 通常,任何重新进入锁的尝试都会导致死锁,并且死锁非常难调试。 作为开发的辅助手段,System.Threading.SpinLock 支持一种线程跟踪模式,当线程尝试重新进入它已经持有的锁时,此模式将会导致引发异常。 这将让您更易于定位到锁未正确退出的点。 通过使用一个采用布尔输入形参的 SpinLock 构造函数并传入 true 实参,可以启用线程跟踪模式。 完成开发和测试阶段之后,应关闭线程跟踪模式以获得更好的性能。

    使用SpinLock的Demo:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace MyConsole2
    {
        class Program
        {
            const int N = 10000;
            static Queue<Data> _queue = new Queue<Data>();
            static object _lock = new object();
            static SpinLock _spinlock = new SpinLock();
            class Data
            {
                public string Name { get; set; }
                public double Number { get; set; }
            }
    
            static void UpdateWithSpinLock(Data d, int i)
            {
                bool lockTaken = false;
                try
                {
                    _spinlock.Enter(ref lockTaken);
                    _queue.Enqueue(d);
                }
                finally
                {
                    if (lockTaken) _spinlock.Exit(false);
                }
                 
            }
    
            static void UseSpinLock()
            {
                Stopwatch sw = Stopwatch.StartNew();
    
                Parallel.Invoke(()=> {
                    for (int i = 0; i < N; i++)
                    {
                        UpdateWithSpinLock(new Data() { Name = i.ToString(), Number = i }, i);
                    }
                },
                ()=> {
                    for (int i = 0; i < N; i++)
                    {
                        UpdateWithSpinLock(new Data() { Name = i.ToString(), Number = i }, i);
                    }
                });
    
                sw.Stop();
                Console.WriteLine("elapsed ms with spinlock: {0}", sw.ElapsedMilliseconds);
    
            }
    
            static void UpdateWithLock(Data d, int i)
            {
                lock (_lock)
                {
                    _queue.Enqueue(d);
                }
            }
    
            private static void UseLock()
            {
                Stopwatch sw = Stopwatch.StartNew();
    
                Parallel.Invoke(
                        () => {
                            for (int i = 0; i < N; i++)
                            {
                                UpdateWithLock(new Data() { Name = i.ToString(), Number = i }, i);
                            }
                        },
                        () => {
                            for (int i = 0; i < N; i++)
                            {
                                UpdateWithLock(new Data() { Name = i.ToString(), Number = i }, i);
                            }
                        }
                    );
                sw.Stop();
                Console.WriteLine("elapsed ms with lock: {0}", sw.ElapsedMilliseconds);
            }
            static void Main(string[] args)
            {
                UseLock();
                _queue.Clear();
                UseSpinLock();
    
                Console.ReadLine();
            }        
    
        }
    
    }
  • 相关阅读:
    [Reproduced]BIOS -- Basic Input and Output System
    What is CSM mode?
    java.lang.UnsupportedOperationException: Can't convert to color: type=0x2 In TextInputLayout
    What is “passive data structure” in Android/Java?
    Android Studio 手动配置 Gradle
    ScrollView内嵌ListView,ListView显示不全及滑动冲突的问题
    Android安全开发之Provider组件安全
    Android permission and uses-permission
    PriorityBlockingQueue(带优先级的阻塞队列)
    Lesson: Generics (Updated)
  • 原文地址:https://www.cnblogs.com/goodlucklzq/p/4488105.html
Copyright © 2011-2022 走看看