C# 锁

JohnnyLei's Blog / 2023-07-24 / 原文

代码

using System.Diagnostics;

namespace ConsoleAppLockDemo
{
    internal  class Program
    {
        static object lockobj = new object();
        static ReaderWriterLockSlim readerWriterLockSlim = new ReaderWriterLockSlim();
        static ReaderWriterLock readerWriterLock = new ReaderWriterLock();
        static Semaphore semaphore = new Semaphore(1, 1);
        static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1);
        static AutoResetEvent autoResetEvent = new AutoResetEvent(true);
        static ManualResetEvent manualResetEvent = new ManualResetEvent(true);
        static ManualResetEventSlim manualResetEventSlim = new ManualResetEventSlim(true);
        static Mutex mutex = new Mutex();
        static async Task Main(string[] args)
        {


            //外循环数量
            int outerLoopCount = 1;
            //线程数量
            int ThreadNum = 1000000;

            Stopwatch stopwatch = new Stopwatch();
            await GetTest(outerLoopCount, ThreadNum, stopwatch);
            ThreadNum = 100000;
            await GetTest(outerLoopCount, ThreadNum, stopwatch);
            ThreadNum = 10000;
            await GetTest(outerLoopCount, ThreadNum, stopwatch);
            ThreadNum = 1000;
            await GetTest(outerLoopCount, ThreadNum, stopwatch);
            ThreadNum = 100;
            await GetTest(outerLoopCount, ThreadNum, stopwatch);
            ThreadNum = 10;
            await GetTest(outerLoopCount, ThreadNum, stopwatch);
            Console.ReadLine();
        }

        private static async Task GetTest(int outerLoopCount, int ThreadNum, Stopwatch stopwatch)
        {
            //1 原子锁
            #region 原子锁
            int islock = 0;
            int countInterlocked = 0;
            stopwatch.Restart();
            for (int j = 0; j < outerLoopCount; j++)
            {
                for (int i = 0; i < ThreadNum; i++)
                {
                    await Task.Factory.StartNew(() =>
                    {
                        while (Interlocked.CompareExchange(ref islock, 1, 0) == 1)
                        {


                        }
                        countInterlocked = countInterlocked + 2;
                        Interlocked.Exchange(ref islock, 0);
                    });

                }
            }

            stopwatch.Stop();

            Console.WriteLine($">>Interlocked.Exchange\t外循环数量:{outerLoopCount},线程数量:{ThreadNum},执行时间:{stopwatch.ElapsedMilliseconds} ms,单循环{ThreadNum}线程: 执行速度:{stopwatch.ElapsedMilliseconds * 1.0 / outerLoopCount} ms/单循环");
            #endregion
            //2 临界锁

            #region 临界锁

            int countlockobj = 0;

            stopwatch.Restart();
            for (int j = 0; j < outerLoopCount; j++)
            {
                for (int i = 0; i < ThreadNum; i++)
                {
                    await Task.Factory.StartNew(() =>
                    {

                        lock (lockobj)
                        {

                            countlockobj = countlockobj + 2;
                        }
                    });

                }
            }
            stopwatch.Stop();

            Console.WriteLine($">>lock\t\t\t外循环数量:{outerLoopCount},线程数量:{ThreadNum},执行时间:{stopwatch.ElapsedMilliseconds} ms,单循环{ThreadNum}线程: 执行速度:{stopwatch.ElapsedMilliseconds * 1.0 / outerLoopCount} ms/单循环");

            int InterlockedCount = 0;
            #endregion

            //3 原子性操作
            #region 原子性操作
            stopwatch.Restart();
            for (int j = 0; j < outerLoopCount; j++)
            {
                for (int i = 0; i < ThreadNum; i++)
                {
                    await Task.Factory.StartNew(() =>
                    {



                        Interlocked.Add(ref InterlockedCount, 2);

                    });

                }
            }
            stopwatch.Stop();

            int InterlockedCount2 = 0;
            Console.WriteLine($">>Interlocked Add\t外循环数量:{outerLoopCount},线程数量:{ThreadNum},执行时间:{stopwatch.ElapsedMilliseconds} ms,单循环{ThreadNum}线程: 执行速度:{stopwatch.ElapsedMilliseconds * 1.0 / outerLoopCount} ms/单循环");


            stopwatch.Restart();
            for (int j = 0; j < outerLoopCount; j++)
            {
                for (int i = 0; i < ThreadNum; i++)
                {
                    await Task.Factory.StartNew(() =>
                    {



                        Interlocked.Increment(ref InterlockedCount2);

                    });

                }
            }

            stopwatch.Stop();
            Console.WriteLine($">>Interlocked Increment\t外循环数量:{outerLoopCount},线程数量:{ThreadNum},执行时间:{stopwatch.ElapsedMilliseconds} ms,单循环{ThreadNum}线程: 执行速度:{stopwatch.ElapsedMilliseconds * 1.0 / outerLoopCount} ms/单循环");

            #endregion
            //4 读写锁
            #region 读写锁
            int ReaderWriterLockCount = 0;

            stopwatch.Restart();
            for (int j = 0; j < outerLoopCount; j++)
            {

                for (int i = 0; i < ThreadNum; i++)
                {
                    await Task.Factory.StartNew(() =>
                    {
                        readerWriterLockSlim.EnterWriteLock();


                        ReaderWriterLockCount = ReaderWriterLockCount + 2;
                        readerWriterLockSlim.ExitWriteLock();
                    });

                }
            }


            stopwatch.Stop();
            Console.WriteLine($">>ReaderWriterLockSlim\t外循环数量:{outerLoopCount},线程数量:{ThreadNum},执行时间:{stopwatch.ElapsedMilliseconds} ms,单循环{ThreadNum}线程: 执行速度:{stopwatch.ElapsedMilliseconds * 1.0 / outerLoopCount} ms/单循环");
            int ReaderWriterLockCount3 = 0;

            ///

            stopwatch.Restart();
            for (int j = 0; j < outerLoopCount; j++)
            {
                for (int i = 0; i < ThreadNum; i++)
                {
                    await Task.Factory.StartNew(() =>
                    {
                        readerWriterLock.AcquireWriterLock(2000);


                        ReaderWriterLockCount3 = ReaderWriterLockCount3 + 2;
                        readerWriterLock.ReleaseWriterLock();
                    });

                }

            }


            stopwatch.Stop();
            Console.WriteLine($">>ReaderWriterLock\t外循环数量:{outerLoopCount},线程数量:{ThreadNum},执行时间:{stopwatch.ElapsedMilliseconds} ms,单循环{ThreadNum}线程: 执行速度:{stopwatch.ElapsedMilliseconds * 1.0 / outerLoopCount} ms/单循环");

            #endregion
            //5 信号量

            #region 信号量

            int SemaphoreCount = 0;
            stopwatch.Restart();
            for (int j = 0; j < outerLoopCount; j++)
            {

                for (int i = 0; i < ThreadNum; i++)
                {
                    await Task.Factory.StartNew(() =>
                    {
                        semaphore.WaitOne();


                        SemaphoreCount = SemaphoreCount + 2;
                        semaphore.Release();
                    });

                }
            }

            stopwatch.Stop();
            Console.WriteLine($">>Semaphore\t\t外循环数量:{outerLoopCount},线程数量:{ThreadNum},执行时间:{stopwatch.ElapsedMilliseconds} ms,单循环{ThreadNum}线程: 执行速度:{stopwatch.ElapsedMilliseconds * 1.0 / outerLoopCount} ms/单循环");


            int semaphoreSlimCount = 0;
            stopwatch.Restart();
            for (int j = 0; j < outerLoopCount; j++)
            {
                for (int i = 0; i < ThreadNum; i++)
                {
                    await Task.Factory.StartNew(() =>
                    {
                        semaphoreSlim.Wait();
                        //or
                        //semaphoreSlim.Wait(2000);

                        semaphoreSlimCount = semaphoreSlimCount + 2;
                        semaphoreSlim.Release();
                    });

                }
            }

            stopwatch.Stop();
            Console.WriteLine($">>SemaphoreSlim\t\t外循环数量:{outerLoopCount},线程数量:{ThreadNum},执行时间:{stopwatch.ElapsedMilliseconds} ms,单循环{ThreadNum}线程: 执行速度:{stopwatch.ElapsedMilliseconds * 1.0 / outerLoopCount} ms/单循环");

            #endregion
            //6 事件 
            //初始化为true
            #region 事件 


            int autoResetEventCount = 0;
            stopwatch.Restart();

            for (int j = 0; j < outerLoopCount; j++)
            {
                for (int i = 0; i < ThreadNum; i++)
                {
                    await Task.Factory.StartNew(() =>
                    {
                        autoResetEvent.WaitOne();
                        //or
                        //autoResetEvent.WaitOne(2000 );


                        autoResetEventCount = autoResetEventCount + 2;
                        autoResetEvent.Set();
                    });

                }
            }

            stopwatch.Stop();
            Console.WriteLine($">>AutoResetEvent\t外循环数量:{outerLoopCount},线程数量:{ThreadNum},执行时间:{stopwatch.ElapsedMilliseconds} ms,单循环{ThreadNum}线程: 执行速度:{stopwatch.ElapsedMilliseconds * 1.0 / outerLoopCount} ms/单循环");
       



            int manualResetEventCount = 0;
            stopwatch.Restart();
            for (int j = 0; j < outerLoopCount; j++)
            {
                for (int i = 0; i < ThreadNum; i++)
                {
                    await Task.Factory.StartNew(() =>
                    {
                        manualResetEvent.WaitOne();
                        manualResetEventCount = manualResetEventCount + 2;
                        manualResetEvent.Set();
                    });

                }
            }

            stopwatch.Stop();
            Console.WriteLine($">>ManualResetEvent\t外循环数量:{outerLoopCount},线程数量:{ThreadNum},执行时间:{stopwatch.ElapsedMilliseconds} ms,单循环{ThreadNum}线程: 执行速度:{stopwatch.ElapsedMilliseconds * 1.0 / outerLoopCount} ms/单循环");
 




            int manualResetEventSlimCount = 0;

            stopwatch.Restart();
            for (int j = 0; j < outerLoopCount; j++)
            {
                for (int i = 0; i < ThreadNum; i++)
                {
                    await Task.Factory.StartNew(() =>
                    {
                        manualResetEventSlim.Wait();



                        manualResetEventSlimCount = manualResetEventSlimCount + 2;
                        manualResetEventSlim.Set();
                    });

                }
            }

            stopwatch.Stop();
            Console.WriteLine($">>ManualResetEventSlim\t外循环数量:{outerLoopCount},线程数量:{ThreadNum},执行时间:{stopwatch.ElapsedMilliseconds} ms,单循环{ThreadNum}线程: 执行速度:{stopwatch.ElapsedMilliseconds * 1.0 / outerLoopCount} ms/单循环");
      
            #endregion
            //7 互斥 
            #region 互斥

            int mutexCount = 0;
            stopwatch.Restart();
            for (int j = 0; j < outerLoopCount; j++)
            {
                for (int i = 0; i < ThreadNum; i++)
                {
                    await Task.Factory.StartNew(() =>
                    {
                        mutex.WaitOne();



                        mutexCount = mutexCount + 2;
                        mutex.ReleaseMutex();
                    });

                }
            }
            stopwatch.Stop();
            Console.WriteLine($">>Mutex\t\t\t外循环数量:{outerLoopCount},线程数量:{ThreadNum},执行时间:{stopwatch.ElapsedMilliseconds} ms,单循环{ThreadNum}线程: 执行速度:{stopwatch.ElapsedMilliseconds * 1.0 / outerLoopCount} ms/单循环");

            #endregion
        }
    }
}