本地锁


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");
    }
}