0

0

c# lock的性能损耗到底有多大 lock和无锁操作性能对比

煙雲

煙雲

发布时间:2026-01-12 12:08:02

|

417人浏览过

|

来源于php中文网

原创

lock无竞争时开销极低(纳秒级),真正损耗在阻塞引发的上下文切换(几十微秒);推荐用Interlocked替代简单计数,读多写少场景优先用ReaderWriterLockSlim。

c# lock的性能损耗到底有多大 lock和无锁操作性能对比

lock 的性能损耗在什么量级?

在无竞争(即几乎没线程抢锁)时,lock 的开销极低——现代 .NET(6+)会先自旋几轮,不进内核,耗时通常

典型对比(1000 万次计数操作,单核模拟竞争):

  • Interlocked.Increment(ref x):约 80–120 ms
  • lock(obj) { x++; }:约 450–900 ms(取决于争抢强度)
  • Mutex.WaitOne():常超 3000 ms(跨进程开销大)

什么时候该换 Interlocked 而不是 lock?

只要你的临界区只干一件事:读/写/更新一个字段(int、bool、引用等),且逻辑不依赖其他变量或状态判断,就该用 Interlocked

常见误用场景:

  • lock 保护一个 if (count > 0) count--; —— 这其实是「读-判-改」三步,lock 正确但过重
  • ✅ 改成 if (Interlocked.Decrement(ref count) >= 0) { /* 成功减了 */ } —— 原子 CAS,无锁,更快更安全
  • ✅ 计数器、开关标志、引用替换(Interlocked.Exchange)、初始化单例(Interlocked.CompareExchange)都适合

lock 真正的代价不在“加锁”,而在“阻塞”

lock 本身不慢,慢的是线程被迫挂起 + 唤醒带来的上下文切换。一个被阻塞的线程要经历:用户态 → 内核态 → 睡眠队列 → 调度唤醒 → 用户态,这过程至少耗费几十微秒,还吃 CPU 调度资源。

实操建议:

Packify
Packify

Packify 是一个创新的AI包装设计工具

下载
  • 避免在 lock 块里做 I/O、网络调用、Thread.Sleep、复杂计算——这些会让锁持有时间变长,放大争抢
  • 不要用 string 或装箱值类型(如 (object)123)当锁对象——每次都是新对象,根本锁不住
  • 优先用 private static readonly object _lock = new object();,别用 this 或 public 成员,防外部干扰

读多写少?别硬扛 lock,试试 ReaderWriterLockSlim

如果你的字段被读取几千次,只写几次(比如配置缓存、设备状态),lock 就是瓶颈:所有读操作也得排队。

换成 ReaderWriterLockSlim 后,读可以并发,写才互斥:

private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
private int _value;

public int Value { get { _rwLock.EnterReadLock(); try { return _value; } finally { _rwLock.ExitReadLock(); } } set { _rwLock.EnterWriteLock(); try { _value = value; } finally { _rwLock.ExitWriteLock(); } } }

注意:它比 lock 略重(多一层状态管理),但读并发提升明显;若读写比例 Interlocked 或 volatile + 规则约束。

真正容易被忽略的一点:锁的粒度永远比锁的种类更重要。哪怕你用了 Interlocked,如果把它套在一个高频循环里反复调用,也比把几个相关字段打包进一个轻量 lock 块更慢——因为函数调用和内存屏障本身也有成本。

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

731

2023.08.22

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

196

2023.11.20

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

196

2023.11.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

534

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

51

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

194

2025.08.29

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

3

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号