Lock、Monitor线程锁

  • Lock、Monitor线程锁已关闭评论
  • 79 次浏览
  • A+
所属分类:.NET技术
摘要

https://learn.microsoft.com/zh-cn/dotnet/api/system.threading.monitor?view=net-8.0Lock关键字实际上是一个语法糖,它将Monitor对象进行封装,给object加上一个互斥锁,A进程进入此代码段时,会给object对象加上互斥锁,此时其他B进程进入此代码段时检查object对象是否有锁?如果有锁则继续等待A进程运行完该代码段并且解锁object对象之后,B进程才能够获取object对象为其加上锁,访问代码段。
lock 是 Monitor 的语法糖


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;         }     } }  

执行如下图:
Lock、Monitor线程锁
Lock、Monitor线程锁

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