Lock、Monitor线程锁

Lock、Monitor线程锁 Monitor Lock、 Lock 线程锁

Lock、Monitor线程锁

官网使用

https://learn.microsoft.com/zh-cn/dotnet/api/system.threading.monitor?view=net-8.0

一. Lock

1.1介绍

Lock关键字实际上是一个语法糖,它将Monitor对象进行封装,给object加上一个互斥锁,A进程进入此代码段时,会给object对象加上互斥锁,此时其他B进程进入此代码段时检查object对象是否有锁?如果有锁则继续等待A进程运行完该代码段并且解锁object对象之后,B进程才能够获取object对象为其加上锁,访问代码段。
lock 是 Monitor 的语法糖

1.2 示例

lock示例:

private static object obj = new object();
lock (obj)
{
    // 代码逻辑
}

二. Monitor

2.1 介绍

提供同步访问对象的机制。

2.2 示例

Monitor示例:

private static object obj = new object();
try
{
    Monitor.Enter(obj);
    // 代码逻辑
}
catch(Exception ex)
{
    
}
finally
{
    Monitor.Exit(obj);
}

上面两段的代码是一样的意思
但我更喜欢Monitor的写法, 因为这样写可以更加灵活。

2.3 实例

环境: .net 7.0
WebApi中使用Monitor
需求: 当一个线程进来是,挡住其他线程进来,只有当第一个线程执行完之后,其他线程才能进来。

using Microsoft.AspNetCore.Mvc;
using System.Runtime.CompilerServices;

namespace blog.Api.Controller.LockingMechanism
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class LockingMechanismController : ControllerBase
    {
        private static object obj = new object();
        [HttpGet]
        public JsonResult TestLock(string type)
        {

            //bool isGetLock = false;
            //bool acquiredLock = false;
            //object obj = new object();

            string msg = "操作成功";
            int code = 200;

            bool acquiredLock = false;

            try
            {
                Monitor.TryEnter(obj, 500, ref acquiredLock);
                if (acquiredLock)
                {
                    for (int i = 0; i < 10; i++)
                    {
                        Console.WriteLine("资源被锁定中");
                        Thread.Sleep(1000);
                    }
                }
                else
                {
                    Console.WriteLine("锁还没有释放,请稍等");
                    JsonResult json2 = new JsonResult(new
                    {
                        code = code,
                        msg = "锁还没有释放,请稍等",
                        type
                    });
                    //obj = new object();
                    return json2;
                }
            }
            finally
            {
                if (acquiredLock)
                {
                    Monitor.Exit(obj);
                }
                Console.WriteLine("资源已释放!");
            }

            JsonResult json = new JsonResult(new
            {
                code = code,
                msg = msg,
                type
            });
            return json;
        }
    }
}

执行如下图:

当线程1正在执行时,线程2返回锁没释放。

评论