- A+
所属分类:.NET技术
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; } } }
执行如下图: