C#多线程系列之多线程锁lock和Monitor
在多线程编程中,为了保证数据的安全性和正确性,需要使用到锁。本文主要介绍C#中的多线程锁lock和Monitor。
什么是锁?
锁是一种同步机制,可以确保多个线程在访问共享资源时不会产生冲突。在执行某个代码块时,只有获得了锁的线程才能执行,其他线程则需要等待锁的释放。这样可以保证同一时刻只有一个线程对共享资源进行修改,保证数据的安全性。
lock
使用C#中的lock
关键字可以实现锁操作。lock会自动获取一个对象锁,该对象可以是任何引用类型的变量,通常我们使用对象实例来锁住一个代码块。在其他线程尝试访问该代码块时,需要等待锁的释放。
lock的语法如下:
lock(obj)
{
//代码块
}
其中,obj表示锁定的对象, {}之间的代码块为需要锁定的代码块。
下面是一个使用lock的示例:
class Counter
{
private int _count = 0;
public void Increment()
{
lock (this)
{
_count++;
}
}
public int Count
{
get { return _count; }
}
}
class Program
{
static void Main(string[] args)
{
Counter counter = new Counter();
for (int i = 0; i < 10; i++)
{
new Thread(() =>
{
for (int j = 0; j < 1000; j++)
{
counter.Increment();
}
}).Start();
}
Thread.Sleep(1000);
Console.WriteLine($"Count: {counter.Count}");
Console.ReadKey();
}
}
在上述示例中,Counter
类中的Increment()
方法需要对_count
字段进行操作,为了保证数据的安全性,使用了lock代码块对_count++
操作进行锁定,使用this关键字锁住整个类对象实例。
在Main函数中,启动了10个线程对计数器进行操作,最后输出计数器的值。
Monitor
除了lock关键字之外,C#中还提供了一个更灵活的互斥机制Monitor
类,它比lock更准确地控制锁。
Monitor类提供了如下几个方法:
Enter(Object)
:获取对象的锁定。Exit(Object)
:释放对象的锁定。Pulse(Object)
:通知正在等待该对象锁定的一个线程(等待队列中的第一个)该状态的变化。PulseAll(Object)
:通知正在等待该对象锁定的所有线程该状态的变化。Wait(Object)
:使当前线程等待直到其他线程调用该对象的Monitor.Pulse()或Monitor.PulseAll()方法来通知它该状态的变化。
Monitor的语法如下:
lock(LockObject)
{
try
{
Monitor.Enter(LockObject); // 获取对象锁
// 代码块
}
finally
{
Monitor.Exit(LockObject); // 释放对象锁
}
}
Enter
和Exit
方法成对出现,使用try/finally
来确保在代码块执行结束时一定会释放锁。
class Counter
{
private object _locker = new object();
private int _count = 0;
public void Increment()
{
Monitor.Enter(_locker);
try
{
_count++;
}
finally
{
Monitor.Exit(_locker);
}
}
public int Count
{
get { return _count; }
}
}
class Program
{
static void Main(string[] args)
{
Counter counter = new Counter();
for (int i = 0; i < 10; i++)
{
new Thread(() =>
{
for (int j = 0; j < 1000; j++)
{
counter.Increment();
}
}).Start();
}
Thread.Sleep(1000);
Console.WriteLine($"Count: {counter.Count}");
Console.ReadKey();
}
}
上述示例中使用Monitor类实现了同样的功能,创建了一个对象锁_locker, 在Increment()
方法中获取对象锁和释放对象锁。
总结
本文简单介绍了C#中的多线程锁lock
和Monitor
,并提供了简单的示例代码来演示使用方法。在编写多线程程序时,使用锁来保证数据安全性十分重要。在代码的编写过程中,需要注意锁的范围和粒度,粗粒度的锁会抑制性能。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#多线程系列之多线程锁lock和Monitor - Python技术站