c# 多线程环境下控制对共享资源访问的办法
- Monitor:
- 定义:
Monitor是 C# 中最基本的同步机制,通过Enter和Exit方法来控制对共享资源的访问。它提供了排他锁的功能,确保在任何时刻只有一个线程可以访问共享资源。 - 优点:简单易用,适合对临界区进行粗粒度的同步控制。
- 缺点:只能实现排它锁,不能实现读写锁,性能相对较低。
- 定义:

class Program
{
static readonly object _lock = new object();
static int _counter = 0; static void Main()
{
for (int i = 0; i < 10; i++)
{
new Thread(IncrementCounter).Start();
} Console.ReadKey();
} static void IncrementCounter()
{
lock (_lock)
{
_counter++;
Console.WriteLine($"Counter: {_counter}");
}
}
}
- Mutex:
- 定义:
Mutex是一个操作系统对象,用于在进程间共享,通过WaitOne和ReleaseMutex来控制对共享资源的访问。它提供了进程间的同步能力。 - 优点:可跨进程使用,适合在进程间进行同步。
- 缺点:相比
Monitor,性能开销较大,因为涉及到系统调用。
- 定义:

class Program
{
static Mutex _mutex = new Mutex();
static int _counter = 0; static void Main()
{
for (int i = 0; i < 10; i++)
{
new Thread(IncrementCounter).Start();
} Console.ReadKey();
} static void IncrementCounter()
{
_mutex.WaitOne();
_counter++;
Console.WriteLine($"Counter: {_counter}");
_mutex.ReleaseMutex();
}
}
Mutex
- ReaderWriterLockSlim:
- 定义:
ReaderWriterLockSlim实现了读写分离锁,允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。这种机制适用于读多写少的场景。 - 优点:适合读多写少的场景,提高了并发性能。
- 缺点:相对复杂,可能会引起死锁,不支持递归锁。
- 定义:

class Program
{
static ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
static int _counter = 0; static void Main()
{
for (int i = 0; i < 5; i++)
{
new Thread(ReadCounter).Start();
new Thread(IncrementCounter).Start();
} Console.ReadKey();
} static void ReadCounter()
{
_rwLock.EnterReadLock();
Console.WriteLine($"Counter: {_counter}");
_rwLock.ExitReadLock();
} static void IncrementCounter()
{
_rwLock.EnterWriteLock();
_counter++;
Console.WriteLine($"Counter incremented to: {_counter}");
_rwLock.ExitWriteLock();
}
}
ReaderWriterLockSlim
- Semaphore:
- 定义:
Semaphore是一个信号量,用于控制同时访问共享资源的线程数量。通过WaitOne和Release方法,可以控制访问资源的线程数量。 - 优点:可以控制多个线程同时访问共享资源的数量,灵活性较高。
- 缺点:相对于其他机制,使用起来较为复杂,需要谨慎处理信号量的释放。
- 定义:

class Program
{
static Semaphore _semaphore = new Semaphore(2, 2); // Allow 2 threads to access the resource simultaneously
static int _counter = 0; static void Main()
{
for (int i = 0; i < 5; i++)
{
new Thread(IncrementCounter).Start();
} Console.ReadKey();
} static void IncrementCounter()
{
_semaphore.WaitOne();
_counter++;
Console.WriteLine($"Counter: {_counter}");
_semaphore.Release();
}
}
Semaphore
- SemaphoreSlim:
- 定义:
SemaphoreSlim是轻量级的信号量,与Semaphore类似,用于控制同时访问共享资源的线程数量,但相比Semaphore更轻量级。 - 优点:相比
Semaphore,SemaphoreSlim的开销更小,适用于资源访问频繁的场景。 - 缺点:与
Semaphore相比,功能上略有限制,例如没有Release(Int32)方法,只能递增信号量一个单位。
- 定义:

class Program
{
static SemaphoreSlim _semaphore = new SemaphoreSlim(2, 2); // Allow 2 threads to access the resource simultaneously
static int _counter = 0; static void Main()
{
for (int i = 0; i < 5; i++)
{
new Thread(IncrementCounter).Start();
} Console.ReadKey();
} static void IncrementCounter()
{
_semaphore.Wait();
_counter++;
Console.WriteLine($"Counter: {_counter}");
_semaphore.Release();
}
}
SemaphoreSlim
- lock:
- 定义:
lock是 C# 中的关键字,用于在代码块级别实现互斥锁,保护共享资源不被多个线程同时访问。 - 优点:简单易用,适合对临界区进行细粒度的同步控制,编写起来比较方便。
- 缺点:只能用于单线程内部的同步,不能跨越线程或进程,如果不小心使用会导致死锁。
- 定义:

class Program
{
static readonly object _lock = new object();
static int _counter = 0; static void Main()
{
for (int i = 0; i < 5; i++)
{
new Thread(IncrementCounter).Start();
} Console.ReadKey();
} static void IncrementCounter()
{
lock (_lock)
{
_counter++;
Console.WriteLine($"Counter: {_counter}");
}
}
}
lock
c# 多线程环境下控制对共享资源访问的办法的更多相关文章
- 什么是多线程环境下的伪共享(false sharing)?
伪共享是多线程系统(每个处理器有自己的局部缓存)中一个众所周知的性能问 题.伪共享发生在不同处理器的上的线程对变量的修改依赖于相同的缓存行,如 下图所示: 伪共享问题很难被发现,因为线程可能访问完全不 ...
- SQLite在多线程环境下的应用
文一 SQLite的FAQ里面已经专门说明,先贴出来.供以后像我目前的入门者学习. (7) 多个应用程序或者同一个应用程序的多个例程能同时存取同一个数据库文件吗? 多进程可以同时打开同一个数据库,也可 ...
- HttpClient在多线程环境下踩坑总结
问题现场 在多线程环境下使用HttpClient组件对某个HTTP服务发起请求,运行一段时间之后发现客户端主机CPU利用率呈现出下降趋势,而不是一个稳定的状态. 而且,从程序日志中判断有线程处于han ...
- C++多线程环境下的构造函数
多线程的环境里,我们总不可避免要使用锁.于是一个常见的场景就是: class ObjectWithLock { private: std::mutex mtx_; SomeResType shared ...
- Asp.Net在多线程环境下的状态存储问题
在应用开发中,我们经常需要设置一些上下文(Context)信息,这些上下文信息一般基于当前的会话(Session),比如当前登录用户的个人信息:或者基于当前方法调用栈,比如在同一个调用中涉及的多个层次 ...
- 一个由单例模式在多线程环境下引发的 bug
问题症状 HTTP 日志系统,老是出现日志信息覆盖的情况.比如同时调用 A 接口和 B 接口,B 接口请求响应信息变成了 A 接口请求响应相关信息.这个问题在并发量大的情况下越来越严重. 问题初步分析 ...
- C#多线程环境下调用 HttpWebRequest 并发连接限制
C#多线程环境下调用 HttpWebRequest 并发连接限制 .net 的 HttpWebRequest 或者 WebClient 在多线程情况下存在并发连接限制,这个限制在桌面操作系统如 win ...
- 多线程环境下非安全Dictionary引起的“已添加了具有相同键的项”问题
问题: 代码是在多线程环境下,做了简单的Key是否存的判断, 测试代码如下: public class Program { static Dictionary<string, Logger> ...
- 多线程环境下的UI异步操作
转自原文 多线程环境下的UI异步操作 解决VS中,线程间不可互操作的问题,一揽子解决方案: 一.首先,定义一个类:SetControlProperty using System.Reflection; ...
- 单例模式在多线程环境下的lazy模式为什么要加两个if(instance==null)
刚才在看阿寻的博客”C#设计模式学习笔记-单例模式“时,发现了评论里有几个人在问单例模式在多线程环境下为什么lazy模式要加两个if进行判断,评论中的一个哥们剑过不留痕,给他们写了一个demo来告诉他 ...
随机推荐
- 基于centos7的企业级ceph集群搭建[nautilus14.22版]
集群规划 本案例通过ceph-deploy方式部署 主机名 配置 外网IP / 内网IP 角色 系统版本 ceph-node01 磁盘x3 50G 192.168.3.101/24 172.16.1. ...
- TDSQL数据库考试实操题
第一题: 演练二 物理备份(5分) 答: 第二题:2. 演练一 请根据给定的演练方案,进行相关演练,并按如下要求提交截图 主备切换(5分) 答: 第三题:3. 演练一 请根据给定的演练方案,进行相关演 ...
- 大厂边缘组VS小厂核心组,要怎么选?
有问必答 最近有粉丝提问:大厂边缘组VS小厂核心组,怎么选? 这确实是个好问题,读者老爷们可以先问下自己:如果有一份月薪2W在大厂边缘组打螺丝的Offer且不加班,另外还有一份月薪2W5,在小厂核心组 ...
- 深入解读Prometheus Adapter:云原生监控的核心组件
本文详述了Prometheus Adapter的部署与配置,通过三个实践案例展示其在Kubernetes环境中的应用,帮助用户实现基于自定义指标的自动扩展和跨集群统一监控. 关注作者,分享AI全维度知 ...
- python数据分析练习--分析成都的房价
目的:使用python的numpy.pandas.matplotlib库来分析成都二手房的房价信息. 原始数据来源:贝壳找房网站上的数据https://cd.ke.com/ershoufang 环境: ...
- 剑指Offer-60.把二叉树打印成多行(C++/Java)
题目: 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行. 分析: 层次打印二叉树,在打印二叉树结点的同时,保存好结点的左右孩子,不断的重复打印,直到需要打印的数组为空即可. 程序: C ...
- 由于找不到 XINPUT1_3.dll,无法继续执行代码。重新安装程序可能会解决此问题。
---------------------------EpicGamesLauncher.exe - 系统错误---------------------------由于找不到 XINPUT1_3.dl ...
- Java实际工作里用到的几种加密方式
1.Base64加密 最简单的加密方式,甚至可以说不是加密,只是一种用64个字符表示任意二进制数据的方法.Base64编码原理是将输入字符串按字节切分,取得每个字节对应的二进制值(若不足8比特则高位补 ...
- node-sass升级为dart-sass
卸载node-sass npm uninstall node-sass 安装dart-sass npm install sass sass-loader -D 在选择dart-sass版本的时候建议低 ...
- 初识 SpringMVC,运行配置第一个Spring MVC 程序
1. 初识 SpringMVC,运行配置第一个Spring MVC 程序 @ 目录 1. 初识 SpringMVC,运行配置第一个Spring MVC 程序 1.1 什么是 MVC 2. Spring ...