让我详细讲解一下“详解C#线程同步”的完整攻略。
1. 线程同步概述
在多线程编程中,由于多线程之间的运行时序是不确定的,因此需要使用线程同步技术来保证线程安全。C#提供了多种线程同步机制,如锁、互斥量、信号量等。
2. 锁机制
锁机制是最常用的线程同步机制之一。C#中提供了两种类型的锁:Monitor
和lock
。它们都使用关键字lock
来实现。
2.1 Monitor锁
Monitor锁使用Monitor.Enter
和Monitor.Exit
方法来实现锁机制。示例代码如下:
class Program
{
static object locker = new object();
static int counter = 0;
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
Thread thread = new Thread(IncrementCounter);
thread.Start();
}
Console.ReadLine();
}
static void IncrementCounter()
{
Monitor.Enter(locker);
try
{
counter++;
Console.WriteLine($"Current counter value: {counter}");
}
finally
{
Monitor.Exit(locker);
}
}
}
上述代码中,Monitor.Enter
和Monitor.Exit
方法分别用于获得锁和释放锁。多个线程同时访问IncrementCounter
方法时,只有一个线程可以获得锁。
2.2 lock锁
lock锁是一种语法糖,其实现方式和Monitor锁是类似的。示例代码如下:
class Program
{
static object locker = new object();
static int counter = 0;
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
Thread thread = new Thread(IncrementCounter);
thread.Start();
}
Console.ReadLine();
}
static void IncrementCounter()
{
lock (locker)
{
counter++;
Console.WriteLine($"Current counter value: {counter}");
}
}
}
上述代码中,lock
关键字用于获取和释放锁。
3. 互斥量
互斥量是一种系统级别的同步机制,可用于跨进程和跨计算机的线程同步。C#中提供了Mutex
类来实现互斥量。示例代码如下:
class Program
{
static Mutex mutex = new Mutex();
static int counter = 0;
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
Thread thread = new Thread(IncrementCounter);
thread.Start();
}
Console.ReadLine();
}
static void IncrementCounter()
{
mutex.WaitOne();
try
{
counter++;
Console.WriteLine($"Current counter value: {counter}");
}
finally
{
mutex.ReleaseMutex();
}
}
}
上述代码中,Mutex.WaitOne
和Mutex.ReleaseMutex
方法分别用于获取和释放互斥量。
4. 信号量
信号量是一种限制并发访问资源的机制,它可以用于控制同时访问某个资源或者代码块的线程数量。C#中提供了Semaphore
类来实现信号量。
4.1 无参构造函数
Semaphore类的无参构造函数创建一个信号量,初始计数器为0。示例代码如下:
class Program
{
static Semaphore semaphore = new Semaphore(0, 5);
static int counter = 0;
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Thread thread = new Thread(IncrementCounter);
thread.Start();
}
Console.ReadLine();
}
static void IncrementCounter()
{
semaphore.WaitOne();
try
{
counter++;
Console.WriteLine($"Current counter value: {counter}");
}
finally
{
semaphore.Release();
}
}
}
上述代码中,Semaphore类的构造函数中第一个参数为初始计数器(Initial Count),第二个参数为最大计数器(Maximum Count)。创建一个初始计数器为0,最大计数器为5的信号量。Semaphore.WaitOne
方法用于获取信号量,Semaphore.Release
方法用于释放信号量。
4.2 带参数的构造函数
Semaphore类的带参数的构造函数也很常用,它可以设置一个初始值。示例代码如下:
class Program
{
static Semaphore semaphore = new Semaphore(3, 5);
static int counter = 0;
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Thread thread = new Thread(IncrementCounter);
thread.Start();
}
Console.ReadLine();
}
static void IncrementCounter()
{
semaphore.WaitOne();
try
{
counter++;
Console.WriteLine($"Current counter value: {counter}");
}
finally
{
semaphore.Release();
}
}
}
上述代码中,Semaphore类的构造函数中第一个参数为初始计数器(Initial Count),第二个参数为最大计数器(Maximum Count)。创建一个初始计数器为3,最大计数器为5的信号量。
在上述示例中,最多只有3个线程同时运行,其余线程需要等待。
这样,我们就讲解了C#中常用的线程同步机制。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解c# 线程同步 - Python技术站