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() { Monitor.Enter(_lock); try { _counter++; Console.WriteLine($"Counter: {_counter}"); } finally { Monitor.Exit(_lock); } } }
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(); } }
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(); } }
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(); } }
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(); } }
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}"); } } }