本地锁
1、读写锁
ReadWriteLocker
类是在 ReaderWriterLockSlim
类的基础上进行的封装,提供了 LockRead 和 LockWrite 方法。如下所示:
private Dictionary<string, string> _dictionary = new Dictionary<string, string>();
[TestMethod]
public void TestLockWrite()
{
var locker = new ReadWriteLocker();
Parallel.For(0, 5, i =>
{
locker.LockWrite(() =>
{
_dictionary.Add("fireasy", "true");
});
});
}
运行程序你会发现字典并没有出现 key 已存在的异常,表明只有一个线程添加了 key。
2、单例锁
SingletonLocker
类使用 SemaphoreSlim
对象控制请求线程的数量,从而达只有第一个线程才能初始化实例的目的。如下所示:
public class Person
{
public Person()
{
Console.WriteLine(DateTime.Now);
}
}
private Person _person = null;
[TestMethod]
public void TestSingletonLock()
{
Parallel.For(0, 5, i =>
{
_person = SingletonLocker.Lock(ref _person, () => new Person());
});
}
运行程序你会发现 _person 只实例化过一次。
SingletonLocker
类的 Lock 方法还可以指定一个对象作为 locker 参数,此时使用的是 lock 语句块。如下所示:
private Person _person = null;
private object _locker = new object();
[TestMethod]
public void TestSingletonLock()
{
Parallel.For(0, 5, i =>
{
_person = SingletonLocker.Lock(ref _person, _locker, () => new Person());
});
}
3、异步锁
AsyncLocker
类是专为异步编程提供的一种锁机制,因为普通的 lock 无法使用于 await 中。如下所示:
[TestMethod]
public async Task TestAsyncLock()
{
var locker = new AsyncLocker();
using (await locker.LockAsync())
{
await FileIO.WriteTextAsync("c:\1.txt", "fireasy");
}
}