一、基本介绍
锁是一种同步机制,用于控制多个线程对共享资源的访问。当一个线程获得了锁时,其他线程将被阻塞,直到该线程释放了锁。
在并发编程中,多个线程同时访问共享资源可能导致数据竞争和不确定的行为。锁可以确保在任意时刻只有一个线程可以访问共享资源,从而避免竞态条件和数据不一致性问题。
二、锁的作用原理
锁的作用原理通常涉及到内部的互斥机制。当一个线程获得锁时,它会将锁标记为已被占用,其他线程尝试获取该锁时会被阻塞,直到持有锁的线程释放锁。这种互斥机制可以通过不同的算法和数据结构来实现,如互斥量、自旋锁等。
三、常用的线程锁机制
1. lock
语句
lock
语句是C#中最基本的同步机制,它使用一个对象作为锁(通常称为“锁对象”),确保同一时间只有一个线程可以执行锁定代码块。
using System;
using System.Threading;class Program
{static object lockObject = new object();static int sharedResource = 0;static void Main(){Thread thread1 = new Thread(Increment);Thread thread2 = new Thread(Increment);thread1.Start();thread2.Start();thread1.Join();thread2.Join();Console.WriteLine($"Final value: {sharedResource}");}static void Increment(){for (int i = 0; i < 10000; i++){lock (lockObject){sharedResource++;}}}
}
2. Monitor
类
Monitor
类提供了更灵活的锁定机制,它允许等待、通知和超时等高级功能。
using System;
using System.Threading;class Program
{static object lockObject = new object();static int sharedResource = 0;static void Main(){Thread thread1 = new Thread(Increment);Thread thread2 = new Thread(Increment);thread1.Start();thread2.Start();thread1.Join();thread2.Join();Console.WriteLine($"Final value: {sharedResource}");}static void Increment(){for (int i = 0; i < 10000; i++){bool lockTaken = false;try{Monitor.Enter(lockObject, ref lockTaken);sharedResource++;}finally{if (lockTaken){Monitor.Exit(lockObject);}}}}
}
3. Mutex
类
Mutex
类是一种跨进程的同步机制,但它也可以用于线程同步。Mutex
可以被不同的进程或线程持有。
using System;
using System.Threading;class Program
{static Mutex mutex = new Mutex();static void Main(){Thread thread1 = new Thread(Increment);Thread thread2 = new Thread(Increment);thread1.Start();thread2.Start();thread1.Join();thread2.Join();Console.WriteLine($"Final value: {sharedResource}");}static int sharedResource = 0;static void Increment(){for (int i = 0; i < 10000; i++){bool lockTaken = false;try{mutex.WaitOne(); // 请求锁lockTaken = true;sharedResource++;}finally{if (lockTaken){mutex.ReleaseMutex(); // 释放锁}}}}
}
4. Semaphore
类
Semaphore
类允许多个线程同时访问资源,但它限制了同时访问的最大线程数。
using System;
using System.Threading;class Program
{static Semaphore semaphore = new Semaphore(1, 1);static int sharedResource = 0;static void Main(){Thread thread1 = new Thread(Increment);Thread thread2 = new Thread(Increment);thread1.Start();thread2.Start();thread1.Join();thread2.Join();Console.WriteLine($"Final value: {sharedResource}");}static void Increment(){for (int i = 0; i < 10000; i++){semaphore.WaitOne(); // 请求信号量try{sharedResource++;}finally{semaphore.Release(); // 释放信号量}}}
}
5. ReaderWriterLockSlim
类
ReaderWriterLockSlim
类提供了一种机制,允许多个读者同时访问资源,但写者在写入时会独占访问。
using System;
using System.Threading;class Program
{static ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();static int sharedResource = 0;static void Main(){Thread reader1 = new Thread(Read);Thread reader2 = new Thread(Read);Thread writer = new Thread(Write);reader1.Start();reader2.Start();writer.Start();reader1.Join();reader2.Join();writer.Join();Console.WriteLine($"Final value: {sharedResource}");}static void Read(){rwLock.EnterReadLock();try{Console.WriteLine($"Reader reading: {sharedResource}");}finally{rwLock.ExitReadLock();}}static void Write(){rwLock.EnterWriteLock();try{sharedResource++;Console.WriteLine($"Writer updated: {sharedResource}");}finally{rwLock.ExitWriteLock();}}
}