惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
Microsoft Azure Blog
Microsoft Azure Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
B
Blog
Y
Y Combinator Blog
博客园_首页
有赞技术团队
有赞技术团队
博客园 - Franky
腾讯CDC
G
Google Developers Blog
Recent Announcements
Recent Announcements
博客园 - 【当耐特】
D
Docker
The GitHub Blog
The GitHub Blog
MyScale Blog
MyScale Blog
H
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
A
About on SuperTechFans
D
DataBreaches.Net
T
The Blog of Author Tim Ferriss
V
V2EX
U
Unit 42
aimingoo的专栏
aimingoo的专栏
WordPress大学
WordPress大学

博客园 - 彪悍的代码不需要注释

AI编写的离线压测工具 虚拟机ftp安装 openclaw本地安装 Redhat服务器离线安装FTP 使用python脚本提取SVN近10年提交记录 本地VMware Workstation Pro的rhel-server-7.9-x86_64服务器配置本地源 敏感词过滤 限流 幂等性 Windows本地生成SSL证书,用于本地调试 【转】大文件上传原理及C#实现方案 【转】C# 实现接口幂等性的四种方案 WPF创建不规则窗体时WebBrowser控件不显示的问题 QrCode .NET之Kill -15 优雅退出 排查java代码慢-arthas工具 针对clickonce发布后的程序,优化处理省略弹出层 赔率 winform发布ClickOnce到Linux服务器 CentOS obs直播RTMP协议推流到Nginx流媒体服务器到VUE使用HLS直播
彪悍的代码不需要注释 · 2025-05-18 · via 博客园 - 彪悍的代码不需要注释

原子锁通过 `Interlocked.CompareExchange` 实现“无锁”竞争。这种方式适用于简单的原子操作。

private static int isLock;private static int ceInt;
private static void CEIntAdd(){    for (var i = 0; i < runTimes; i++)    {        while (Interlocked.CompareExchange(ref isLock, 1, 0) == 1)        {            Thread.Sleep(1);        }        ceInt++;        Interlocked.Exchange(ref isLock, 0);    }}

View Code

临界区通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。C# 中的 `lock` 语法是临界区(Monitor)的一个语法糖。

private static object obj = new object();private static int lockInt;
private static void LockIntAdd(){    for (var i = 0; i < runTimes; i++)    {        lock (obj)        {            lockInt++;        }    }}

View Code

原子性操作是一种特例,它天生线程安全,无需加锁。

private static int atomicInt;
private static void AtomicIntAdd(){    for (var i = 0; i < runTimes; i++)    {        Interlocked.Increment(ref atomicInt);    }}

View Code

读写锁允许在有其他程序正在写的情况下读取资源,适合读多写少的场景

private static ReaderWriterLockSlim LockSlim = new ReaderWriterLockSlim();private static int lockSlimInt;
private static void LockSlimIntAdd(){    for (var i = 0; i < runTimes; i++)    {        LockSlim.EnterWriteLock();        lockSlimInt++;        LockSlim.ExitWriteLock();    }}

View Code

信号量用于控制对有限资源的并发访问

private static Semaphore sema = new Semaphore(1, 1);private static int semaphoreInt;
private static void SemaphoreIntAdd(){    for (var i = 0; i < runTimes; i++)    {        sema.WaitOne();        semaphoreInt++;        sema.Release();    }}

View Code

事件用于通知线程某些事件已经发生,从而启动后续任务

public static AutoResetEvent autoResetEvent = new AutoResetEvent(true);private static int autoResetEventInt;
private static void AutoResetEventIntAdd(){    for (var i = 0; i < runTimes; i++)    {        if (autoResetEvent.WaitOne())        {            autoResetEventInt++;            autoResetEvent.Set();        }    }}

View Code

互斥量(Mutex)不仅可以处理线程间的资源竞争,还可以处理进程间的资源竞争。

private static Mutex mutex = new Mutex();private static int mutexInt;
private static void MutexIntAdd(){    for (var i = 0; i < runTimes; i++)    {        mutex.WaitOne();        mutexInt++;        mutex.ReleaseMutex();    }}

View Code

性能测试代码

private static int noLockInt;
private static void NoLockIntAdd(){    for (var i = 0; i < runTimes; i++)    {        noLockInt++;    }}

View Code

private static int runTimes = 10000000; // 可以自己设置private static int loopTimes = 10; // 可以自己设置
private static void Run(){    var stopwatch = new Stopwatch();    var taskList = new Task[loopTimes]; // 设置线程数
    Console.WriteLine();    Console.WriteLine($"              线程数:{loopTimes}");    Console.WriteLine($"            执行次数:{runTimes}");    Console.WriteLine($"        校验值应等于:{runTimes * loopTimes}");
    // AtomicIntAdd    stopwatch.Restart();    for (var i = 0; i < loopTimes; i++)    {        taskList[i] = Task.Factory.StartNew(() => { AtomicIntAdd(); });    }    Task.WaitAll(taskList);    Console.WriteLine($"AtomicIntAdd, 总耗时:{stopwatch.ElapsedMilliseconds}毫秒, 校验值:{atomicInt}");
    // CEIntAdd    taskList = new Task[loopTimes];    stopwatch.Restart();    for (var i = 0; i < loopTimes; i++)    {        taskList[i] = Task.Factory.StartNew(() => { CEIntAdd(); });    }    Task.WaitAll(taskList);    Console.WriteLine($"CEIntAdd, 总耗时:{stopwatch.ElapsedMilliseconds}毫秒, 校验值:{ceInt}");
    // LockIntAdd    taskList = new Task[loopTimes];    stopwatch.Restart();    for (var i = 0; i < loopTimes; i++)    {        taskList[i] = Task.Factory.StartNew(() => { LockIntAdd(); });    }    Task.WaitAll(taskList);    Console.WriteLine($"LockIntAdd, 总耗时:{stopwatch.ElapsedMilliseconds}毫秒, 校验值:{lockInt}");
    // MutexIntAdd    taskList = new Task[loopTimes];    stopwatch.Restart();    for (var i = 0; i < loopTimes; i++)    {        taskList[i] = Task.Factory.StartNew(() => { MutexIntAdd(); });    }    Task.WaitAll(taskList);    Console.WriteLine($"MutexIntAdd, 总耗时:{stopwatch.ElapsedMilliseconds}毫秒, 校验值:{mutexInt}");
    // LockSlimIntAdd    taskList = new Task[loopTimes];    stopwatch.Restart();    for (var i = 0; i < loopTimes; i++)    {        taskList[i] = Task.Factory.StartNew(() => { LockSlimIntAdd(); });    }    Task.WaitAll(taskList);    Console.WriteLine($"LockSlimIntAdd, 总耗时:{stopwatch.ElapsedMilliseconds}毫秒, 校验值:{lockSlimInt}");
    // SemaphoreIntAdd    taskList = new Task[loopTimes];    stopwatch.Restart();    for (var i = 0; i < loopTimes; i++)    {        taskList[i] = Task.Factory.StartNew(() => { SemaphoreIntAdd(); });    }    Task.WaitAll(taskList);    Console.WriteLine($"SemaphoreIntAdd, 总耗时:{stopwatch.ElapsedMilliseconds}毫秒, 校验值:{semaphoreInt}");
    // AutoResetEventIntAdd    taskList = new Task[loopTimes];    stopwatch.Restart();    for (var i = 0; i < loopTimes; i++)    {        taskList[i] = Task.Factory.StartNew(() => { AutoResetEventIntAdd(); });    }    Task.WaitAll(taskList);    Console.WriteLine($"AutoResetEventIntAdd, 总耗时:{stopwatch.ElapsedMilliseconds}毫秒, 校验值:{autoResetEventInt}");
    // NoLockIntAdd    taskList = new Task[loopTimes];    stopwatch.Restart();    for (var i = 0; i < loopTimes; i++)    {        taskList[i] = Task.Factory.StartNew(() => { NoLockIntAdd(); });    }    Task.WaitAll(taskList);    Console.WriteLine($"NoLockIntAdd, 总耗时:{stopwatch.ElapsedMilliseconds}毫秒, 校验值:{noLockInt}");    Console.WriteLine();}
private static string GetFormat(string start){    return start + "开始执行";}

View Code

在多线程并发测试中,不同锁的性能表现如下:
1. 无锁:不加锁的代码运行最快,但不适合资源竞争场景。
2. 原子锁:`Interlocked.CompareExchange` 表现出优越的性能,适合简单的原子操作。
3. 临界区:`lock` 关键字实现的临界区表现出良好的性能,适合控制数据访问。
4. 原子性操作:`Interlocked.Increment` 等原子性操作适合变量的自增自减,但适用性有限。
5. 读写锁:`ReaderWriterLockSlim` 支持多线程读取,适合读多写少的场景。
6. 信号量、事件、互斥量:这些锁在处理资源竞争时性能较差,但它们在特定场景下有其适用性。