C#中的Lock、Monitor、Mutex学习笔记
前言
在多线程并发编程中,由于多线程同时执行,并且对共享资源进行访问时需要考虑线程安全,保证线程的执行顺序或者互斥访问,C#提供了三种方式来处理线程同步问题:Lock、Monitor、Mutex。
在本篇学习笔记中,我们将对这三种方式进行全面的讲解。
Lock
Lock是一种轻量级的同步方式,它是由.NET CLR提供的。Lock通过访问内部运行时环境中的Monitor实现,Monitor又是基于一个非常简单的信号机制,在获取锁之后,需要主动释放锁,不释放锁会导致其他线程无法访问同步锁相关资源。
下面是一个使用Lock的示例:
class Program
{
static void Main(string[] args)
{
object lockObject = new object();
int sum = 0;
for (int i = 0; i < 5; i++)
{
Thread t = new Thread(() =>
{
lock (lockObject)
{
for (int j = 0; j < 100; j++)
{
sum++;
}
}
});
t.Start();
}
Console.WriteLine($"The result is: {sum}"); // 输出结果未知
Console.ReadKey();
}
}
在上面的代码中,我们创建了一个包含5个线程,每个线程都会对sum
进行自增操作,但是在多个线程同时修改一个变量时,会产生数据不一致的问题。
这种情况下,我们可以使用lock
来限制只有一个线程能够访问该变量:
class Program
{
static void Main(string[] args)
{
object lockObject = new object();
int sum = 0;
for (int i = 0; i < 5; i++)
{
Thread t = new Thread(() =>
{
lock (lockObject)
{
for (int j = 0; j < 100; j++)
{
sum++;
}
}
});
t.Start();
t.Join(); // 可以确保线程按顺序执行
}
Console.WriteLine($"The result is: {sum}"); // 输出500
Console.ReadKey();
}
}
在上面的代码中,我们使用lock
限制对sum
的访问,只有一个线程可以访问该变量。由于线程执行的速度非常快,所以我们需要使用Join
方法等待线程执行完毕,以确保sum
的值是正确的。
Monitor
Monitor和Lock的工作机制类似,都是使用一个关键字来锁定代码块。但是,Monitor在使用时需要手动调用Acquire和Release方法来控制临界区以提高代码执行效率。
下面是一个使用Monitor的示例:
class Program
{
static void Main(string[] args)
{
object lockObject = new object();
int sum = 0;
for (int i = 0; i < 5; i++)
{
Thread t = new Thread(() =>
{
Monitor.Enter(lockObject);
try
{
for (int j = 0; j < 100; j++)
{
sum++;
}
}
finally
{
Monitor.Exit(lockObject);
}
});
t.Start();
t.Join(); // 可以确保线程按顺序执行
}
Console.WriteLine($"The result is: {sum}"); // 输出500
Console.ReadKey();
}
}
在上面的代码中,我们使用了Monitor.Enter
和Monitor.Exit
方法来代替Lock来控制访问变量的行为。
Mutex
Mutex是一种类似于Lock的同步方式,但是它可以跨进程使用。Mutex可以自动识别持有锁的线程,也可以被释放锁的线程重新获得锁,可以用于跨进程协作和同步。
下面是一个使用Mutex的示例:
class Program
{
static void Main(string[] args)
{
Mutex mutex = new Mutex();
int sum = 0;
for (int i = 0; i < 5; i++)
{
Thread t = new Thread(() =>
{
mutex.WaitOne();
try
{
for (int j = 0; j < 100; j++)
{
sum++;
}
}
finally
{
mutex.ReleaseMutex();
}
});
t.Start();
t.Join(); // 可以确保线程按顺序执行
}
Console.WriteLine($"The result is: {sum}"); // 输出500
Console.ReadKey();
}
}
在上面的代码中,我们使用了Mutex
来实现同步,保证多个线程对变量的访问是单一的,并且可以被多个进程同时使用。
总结
在多线程并发编程中,使用Lock、Monitor、Mutex来同步访问共享资源是必不可少的技术。在使用时需要注意线程访问顺序以及锁的释放,以保证代码的正确性与效率。
本文对Lock、Monitor、Mutex的使用进行了详细的介绍,并提供了示例代码,希望读者能够理解并熟练掌握该技术。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#中的lock、Monitor、Mutex学习笔记 - Python技术站