线程锁是一种同步机制,在多线程中确保共享资源在同一刻只能有一个线程访问;
lock关键字
lock 是由System.Threading.Monitor类封装的语法糖,使用方式如下:
class A
{
//定义一个锁的对象
private readonly object obj=new object();
public void Change()
{
lock(obj)
{
//临界区,此处代码同一刻只能有一个线程访问
//此处尽量不要有长耗时的操作,以防线程等待过多,引发其他异常
}
}
}
Monitor类
System.Threading.Monitor类 是C# 中许多常用锁的底层封装类,常用的几个静态方法;
- Monitor.Enter(Object) 在指定对象上获取排他锁
- Monitor.TryEnter(Object, Int32) 在指定的毫秒数内尝试获取指定对象上的排他锁
- Monitor.Exit(Object) 释放指定对象上的排他锁
class A
{
//定义一个锁的对象
private readonly object obj=new object();
public void Change()
{
Monitor.Enter(obj);
try
{
//临界区,此处代码同一刻只能有一个线程访问
//此处尽量不要有长耗时的操作,以防线程等待过多,引发其他异常
}
finally
{
//需要添加try finally块,以避免因为异常导致的锁没有释放
Monitor.Exit(obj);
}
}
}
特性 [MethodImpl(MethodImplOptions.Synchronized)]
MethodImpl(MethodImplOptions.Synchronized) 是Monitor的封装,用来标记在执行中
[MethodImpl(MethodImplOptions.Synchronized)]
public void FunLock()
{
//实例方法特性标记,只允许同一个实例同一刻只能有一个线程访问,类似 lock(this)
//此处尽量不要有长耗时的操作,以防线程等待过多,引发其他异常
//同时在两个实例并发,锁不会生效,比如var a =new(); var b=new(),分别在两个不同的线程上调用时,锁不会生效,可同时并行
}
/// <summary>
/// 静态 -- lock(obj) private static object,进程内唯一
/// </summary>
[MethodImpl(MethodImplOptions.Synchronized)]
public static void FunLockStatic()
{
//静态方法特性标记,只允许同一刻只能有一个线程访问,类似 lock(obj)
//此处代码逻辑,尽量不要有长耗时的操作,以防线程等待过多,引发其他异常
}