线程与并发系列一:Lock、Monitor、UserSpinLock

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;

namespace MyConsole.ThreadDemo
{
    class Lock
    {
        static int Storeage { get; set; }
        static object LockObject = new object();

        static void Main(string[] args)
        {
            var timer = new Stopwatch();
            var my = new Lock();
            var data = new Dictionary<string, Action>()
            {
                {"错误的代码",my.Wrong},
                {"正解的代码 使用Lock",my.UserLock},
                {"正解的代码 使用Monitor",my.UserMonitor},
                {"使用UserSpinLock",my.UserSpinLock},
            };
            foreach (var item in data)
            {
                Console.WriteLine();
                Console.WriteLine(item.Key);
                timer.Restart();
                my.Being(new ThreadStart(item.Value));
                timer.Stop();
                Console.WriteLine(timer.ElapsedTicks);
            }
        }

        #region = Wrong =
        void Wrong()
        {
            var random = new Random(DateTime.Now.Millisecond);
            var w = random.Next(100);
            Lock.Storeage = w;
            Thread.Sleep(random.Next(1, 5));
            var r = Lock.Storeage;

            Message(w, r);
        } 
        #endregion

        #region = UserLock =
        void UserLock()
        {
            var random = new Random(DateTime.Now.Millisecond);
            var w = random.Next(100);
            var r = -1;
            lock (LockObject)
            {
                Lock.Storeage = w;
                Thread.Sleep(random.Next(100, 500));
                r = Lock.Storeage;
            }

            Message(w, r);
        } 
        #endregion

        #region = UserMonitor =
        void UserMonitor()
        {
            var random = new Random(DateTime.Now.Millisecond);
            var w = random.Next(100);
            var r = -1;
            Monitor.Enter(LockObject);

            Lock.Storeage = w;
            Thread.Sleep(random.Next(100, 500));
            r = Lock.Storeage;
            Monitor.Exit(LockObject);

            Message(w, r);
        }
        #endregion

        #region = UserSpinLock =
        SpinLock _spinlock = new SpinLock();
        void UserSpinLock()
        {
            var random = new Random(DateTime.Now.Millisecond);
            var w = random.Next(100);
            var r = -1;
            var lockTaken = false;
            _spinlock.Enter(ref lockTaken);

            Lock.Storeage = w;
            Thread.Sleep(random.Next(100, 500));
            r = Lock.Storeage;
            _spinlock.Exit();

            Message(w, r);
        }
        #endregion

        #region = Being =
        void Being(ThreadStart start)
        {
            var threads = Enumerable.Range(0, 10).Select(x => new Thread(start)).ToList();//必须ToList一下
            foreach (var item in threads)
            {
                item.Start();
            }

            foreach (var item in threads)
            {
                item.Join();
            }
        } 
        #endregion

        #region - Message -
        static void Message(int w, int r)
        {
            var msg = string.Format("线程{0}在运行 存入{1} 读出{2} {3}",
                Thread.CurrentThread.ManagedThreadId, r, w,
                r == w ? "正确" : "错误");
            Console.WriteLine(msg);
        } 
        #endregion
    }
}

输出

错误的代码
线程5在运行 存入99 读出95 错误
线程4在运行 存入99 读出95 错误
线程6在运行 存入99 读出47 错误
线程3在运行 存入99 读出43 错误
线程8在运行 存入99 读出47 错误
线程7在运行 存入99 读出47 错误
线程9在运行 存入99 读出47 错误
线程10在运行 存入99 读出47 错误
线程12在运行 存入99 读出99 正确
线程11在运行 存入99 读出99 正确
31323

正解的代码 使用Lock
线程13在运行 存入8 读出8 正确
线程14在运行 存入61 读出61 正确
线程16在运行 存入61 读出61 正确
线程15在运行 存入61 读出61 正确
线程18在运行 存入65 读出65 正确
线程17在运行 存入13 读出13 正确
线程20在运行 存入17 读出17 正确
线程19在运行 存入65 读出65 正确
线程22在运行 存入22 读出22 正确
线程21在运行 存入70 读出70 正确
6118886

正解的代码 使用Monitor
线程23在运行 存入90 读出90 正确
线程25在运行 存入90 读出90 正确
线程24在运行 存入90 读出90 正确
线程27在运行 存入95 读出95 正确
线程26在运行 存入95 读出95 正确
线程29在运行 存入56 读出56 正确
线程31在运行 存入65 读出65 正确
线程28在运行 存入52 读出52 正确
线程30在运行 存入61 读出61 正确
线程32在运行 存入70 读出70 正确
6346075

使用UserSpinLock
线程33在运行 存入19 读出19 正确
线程40在运行 存入24 读出24 正确
线程41在运行 存入76 读出76 正确
线程35在运行 存入71 读出71 正确
线程34在运行 存入19 读出19 正确
线程38在运行 存入24 读出24 正确
线程39在运行 存入24 读出24 正确
线程36在运行 存入71 读出71 正确
线程37在运行 存入24 读出24 正确
线程42在运行 存入76 读出76 正确
6018558
原文地址:https://www.cnblogs.com/goodspeed/p/3145138.html