一、lock关键字是C#提供的一个语法糖,底层基于System.Threading.Monitor。用于确保同一时间只有一个线程可以执行某段代码(临界区)
✔ lock 的本质是什么?它是:Monitor.Enter() + try/finally + Monitor.Exit() 的语法糖
private readonly object _lockObj = new object();
lock (_lockObj)
{
// 临界区代码
}
特点:1、互斥性:只允许一个线程进入。2、自动释放:即使发生异常,也会通过finally块释放锁3、不可中断:无法设置超时或取消 4、不能跨进程:仅限于当前appdomain内部 5、性能好:适用于简单的互斥场景
✔ lock 适合什么时候用?
写共享变量
访问字典、列表、队列
文件写入
上位机中共享串口、TCP 数据解析的临界区
二、Monitor类
lock的底层实现就是调用Monitor.Enter/Monitor.exit
提供比lock更细颗度的控制,例如支持超时等待
bool lockTaken = false;
try
{
Monitor.TryEnter(_lockObj, TimeSpan.FromSeconds(1), ref lockTaken);
if (lockTaken)
{
// 临界区
}
}
finally
{
if (lockTaken)
Monitor.Exit(_lockObj);
}
特点:支持TryEnter设置超时,可以手动控制锁的获取与释放,仍为独占锁(一次只能一个线程持有),同样不能跨进程。
✔ Monitor 用于:
生产者/消费者队列
设备消息队列的阻塞式等待
通常在“通信线程 + UI 线程”模型下可能需要。
三、SemaphoreSlim
表示一个轻量级信号量。允许多个线程同时访问资源。但是数量受限制,适用于资源地、限流等场景。
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(3); // 最多3个并发
await _semaphore.WaitAsync(); // 异步等待(推荐)
try
{
// 最多3个线程可同时执行此处
}
finally
{
_semaphore.Release();
}
特点:
支持并发数>1(如数据库连接池最多5个连接)
支持异步等待(WaitAsync()),非常适合async/await场景
支持超时(Wait(TimeSpan) 或 WaitAsync(TimeSpan))
轻量级:相比Semaphore(基于内核对象),Semaphore是纯托管实现,性能更好
不能跨进程(若需跨进程,用 Semaphore 而非 SemaphoreSlim)
SemaphoreSlim 用于:
限制一次最多几条指令发送
限制一个设备一次只能处理 1 个 CRC 运算
控制同时运行的后台任务数量
调度异步 IO 任务
选择建议
如果只是保护一小段代码,确保线程安全 → 用 lock。
如果需要带超时的互斥锁 → 用 Monitor.TryEnter。
如果允许多个线程并发(但有限制),或在 async 方法中做同步 → 用 SemaphoreSlim。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/970960.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!