代码改变世界

读写锁操作(ReaderWriterLockSlim)

2010-05-13 15:53  Clingingboy  阅读(1763)  评论(0编辑  收藏  举报

    
(1)

static void WriterMethod(object writer)
{
    Console.WriteLine("Writer {0} acquired the lock", writer);
    for (int i = 0; i < items.Count; i++)
    {
        items[i]++;
        Console.Write(items[i]);
    }
    Console.WriteLine("");
    Console.WriteLine("Writer {0} finished", writer);
}

private static List<int> items = new List<int>() { 0, 1, 2, 3, 4, 5 };

static void Main()
{
    WriterMethod(0);
    WriterMethod(1);

}

image
没问题
(2)换成线程
for (int i = 0; i < 2; i++)
{
    Thread a = new Thread(WriterMethod);
    a.Start(i);
}

顺序出错了
image

(3)使用读写锁操作ReaderWriterLockSlim
使用EnterWriteLock锁定写操作,恢复正常,必须手动退出锁模式,否则将会永远独占ExitWriteLock

  static void WriterMethod(object writer)
  {
      rwl.EnterWriteLock();
      Console.WriteLine("Writer {0} acquired the lock", writer);
      for (int i = 0; i < items.Count; i++)
      {
          items[i]++;
          Console.Write(items[i]);
      }
      Console.WriteLine("");
      Console.WriteLine("Writer {0} finished", writer);
      rwl.ExitWriteLock();
  }
  private static ReaderWriterLockSlim rwl = new
ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);


(4)设置锁超时时间
使用Try方法是可以设置锁时间,如果超时的话,则继续执行,但此时则未进入锁定状态,无法用ExitWriteLock退出,可以用
RecursiveWriteCount属性来判断

static void WriterMethod(object writer)
{
    rwl.TryEnterWriteLock(50);
    Console.WriteLine("Writer {0} acquired the lock", writer);
    for (int i = 0; i < items.Count; i++)
    {
        items[i]++;
        Console.Write(items[i]);
        Thread.Sleep(50);
    }
    Console.WriteLine("");
    Console.WriteLine("Writer {0} finished", writer);
    if(rwl.RecursiveWriteCount>0)
    rwl.ExitWriteLock();
}
结果照样混乱
image

(5)读写操作(单一执行)

读写操作同时进行
for (int i = 0; i < 2; i++)
{
    Thread a = new Thread(WriterMethod);
    Thread b = new Thread(ReaderMethod);
    b.Start(i);
    a.Start(i);
    
}

static void ReaderMethod(object reader)
{

    for (int i = 0; i < items.Count; i++)
    {
        Console.WriteLine("reader {0}, loop: {1}, item: {2}",
              reader, i, items[i]);
       
    }
    }

结果是混乱的,无法预测

image

进入读操作

static void ReaderMethod(object reader)
{
    rwl.EnterReadLock();
    for (int i = 0; i < items.Count; i++)
    {
        Console.WriteLine("reader {0}, loop: {1}, item: {2}",
              reader, i, items[i]);
     
    }
    rwl.ExitReadLock();
   
}

现在读写操作是单一执行的,不可能同时处于读写状态
image
同样EnterReadLock也有Try方法


另外参见
http://www.cnblogs.com/lucifer1982/archive/2008/12/07/1349437.html