【C#】Lock关键字

一、概述

Lock关键字,确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。

Lock关键字属于语法糖,其本质是Threading.Monitor来控制的。

二、原理

对于任何一个对象来说,它在内存中的第一部分放置的是所有方法的地址,第二部分放着一个索引,这个索引指向CLR中的SyncBlock Cache区域中的一个SyncBlock。

当你执行Monitor.Enter(Object)时,如果object的索引值为负数,就从SyncBlock Cache中选取一个SyncBlock,将其地址放在object的索引中。这样就完成了以object为标志的锁定,其他的线程想再次进行Monitor.Enter(object)操作,将获得object的已经为正值的索引,然后就等待。直到索引变为负数,即调用Monitor.Exit(object)将索引变为负数,等待的线程开始执行。

三、特征

  • 不能锁定空值
  • 不能锁定string类型,整个程序中任何给定字符串都只有一个实例,具有相同内容的字符串都代表着同一个实例。因此,只要在应用程序进程中的任何位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中与该字符串具有相同内容的字符串。因此,最好锁定不会被暂留的私有或受保护成员
  • 锁定的对象是一个程序块的内存边界
  • 值类型不能被Lock
  • 避免锁定public 类型或不受程序控制的对象;如果该实例可以被公开访问,不受控制的代码也可能会锁定该对象。这可能导致死锁,即两个或更多个线程等待释放同一对象。出于同样的原因,锁定公共数据类型(相比于对象)也可能导致问题
  • Unity直接使用Lock机制阻止用户直接在子线程中使用Unity的一些特定属性

四、加锁方式

  • 使用对象本身作为锁对象,对写线程进行加锁
    • 在写线程中,对象将会被锁定,执行完毕之后释放锁,此时对象已经被更改(因为写入操作引起的更改)
  • 使用对象本身作为锁对象,对读线程进行加锁
    • 在读线程中,对象将会被锁定,所以读的过程中对象都将保持不变
  • 使用System.Object作为锁对象
    • 使用其他的引用类型,比如System.Object,此时线程不会访问该类型的任何属性和方法,适用于锁代码块

五、同步块(SyncBlock)

SyncBlock,也称为 Monitor,是在 .NET 平台下用于支持多线程同步的一种机制。它用于实现 C# 中的 lock 关键字和 Monitor 类的功能。

每一个托管对象的头部之前都存在一个Object Header,存储着各种各样的信息,其中就包含SyncBlock的信息。

在多线程编程中,当多个线程同时访问共享资源时,可能会引发竞争条件和数据不一致的问题。SyncBlock 是一种轻量级的同步对象,用于确保对共享资源的互斥访问,从而避免竞争条件和数据不一致性。

当一个线程要进入一个由 Lock 关键字或 Monitor 类保护的代码块时,它会尝试获取 SyncBlock 的所有权。如果 SyncBlock 已被其他线程持有,则当前线程会被阻塞,直到 SyncBlock 可用为止。一旦线程执行完由 lock 关键字或 Monitor 类保护的代码块,它将释放 SyncBlock 的所有权,以便其他线程可以继续访问这个代码块。

相关推荐
喵了meme3 小时前
C语言实战4
c语言·开发语言
码界奇点3 小时前
Python从0到100一站式学习路线图与实战指南
开发语言·python·学习·青少年编程·贴图
9ilk3 小时前
【C++】--- 特殊类设计
开发语言·c++·后端
꧁执笔小白꧂4 小时前
C#+VisionMaster 学习笔记(目录)-目录
c#·visionmaster
sali-tec4 小时前
C# 基于halcon的视觉工作流-章68 深度学习-对象检测
开发语言·算法·计算机视觉·重构·c#
生骨大头菜6 小时前
使用python实现相似图片搜索功能,并接入springcloud
开发语言·python·spring cloud·微服务
绝不收费—免费看不了了联系我6 小时前
Fastapi的单进程响应问题 和 解决方法
开发语言·后端·python·fastapi
消失的旧时光-19436 小时前
深入理解 Java 线程池(二):ThreadPoolExecutor 执行流程 + 运行状态 + ctl 原理全解析
java·开发语言
咖啡续命又一天6 小时前
Trae CN IDE 中 Python 开发的具体流程和配置总结
开发语言·ide·python·ai编程
4311媒体网6 小时前
帝国cms调用文章内容 二开基本操作
java·开发语言·php