C#读写锁ReaderWriterLockSlim的使用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ReaderWriteLockExercise { class Program { static private ReaderWriterLockSlim rwl = new ReaderWriterLockSlim();//读写锁 static void Main(string[] args) { //当某个线程进入读取模式时,此时其他线程依然能进入读取模式,假设此时一个线程要进入写入模式,那么他不得不被阻塞。直到读取模式退出为止。 Task t_read1 = new Task(ReadSomething); t_read1.Start(); Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read1.GetHashCode()); Task t_read2 = new Task(ReadSomething); t_read2.Start(); Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read2.GetHashCode()); //如果某个线程进入了写入模式,那么其他线程无论是要写入还是读取,都是会被阻塞的 Task t_write1 = new Task( WriteSomething); t_write1.Start(); Console.WriteLine("{0} Create Thread ID {1} , Start WriteSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_write1.GetHashCode()); Console.ReadKey(); } static public void ReadSomething() { Console.WriteLine("*************************************读取模式*********************************************"); Console.WriteLine("{0} Thread ID {1} Begin EnterReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); rwl.EnterReadLock();//进入读取模式锁定状态 try { Console.WriteLine("{0} Thread ID {1} reading sth...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); Thread.Sleep(5000);//模拟读取信息 Console.WriteLine("{0} Thread ID {1} reading end.", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); } finally { rwl.ExitReadLock(); Console.WriteLine("{0} Thread ID {1} ExitReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); } } static public void WriteSomething() { Console.WriteLine("***********************************写入模式***************************************************"); Console.WriteLine("{0} Thread ID {1} Begin EnterWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); rwl.EnterWriteLock();//进入写入模式锁定状态 try { Console.WriteLine("{0} Thread ID {1} writing sth...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); Thread.Sleep(10000);//模拟写入信息 Console.WriteLine("{0} Thread ID {1} writing end.", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); } finally { rwl.ExitWriteLock(); Console.WriteLine("{0} Thread ID {1} ExitWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); } } } }
输出结果
02:08:48 270 Create Thread ID 3888474 , Start ReadSomething 02:08:48 341 Create Thread ID 25209742 , Start ReadSomething 02:08:48 341 Create Thread ID 26966483 , Start WriteSomething *************************************读取模式********************************************* 02:08:48 416 Thread ID 1 Begin EnterReadLock... *************************************读取模式********************************************* 02:08:48 417 Thread ID 2 Begin EnterReadLock... 02:08:48 417 Thread ID 1 reading sth... 02:08:48 417 Thread ID 2 reading sth... ***********************************写入模式*************************************************** 02:08:48 506 Thread ID 3 Begin EnterWriteLock... 02:08:53 419 Thread ID 2 reading end. 02:08:53 419 Thread ID 2 ExitReadLock... 02:08:53 419 Thread ID 1 reading end. 02:08:53 420 Thread ID 1 ExitReadLock... 02:08:53 420 Thread ID 3 writing sth... 02:09:03 422 Thread ID 3 writing end. 02:09:03 422 Thread ID 3 ExitWriteLock...
可以看到1号线程和2号线程读取,3号线程5秒后,也就是1和2号线程结束读取模式之后,3号线程开始进入写入模式。
如果将写入线程加到两个,并放在读取线程的前面,如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ReaderWriteLockExercise { class Program { static private ReaderWriterLockSlim rwl = new ReaderWriterLockSlim();//读写锁 static void Main(string[] args) { //如果某个线程进入了写入模式,那么其他线程无论是要写入还是读取,都是会被阻塞的 Task t_write1 = new Task(WriteSomething); t_write1.Start(); Console.WriteLine("{0} Create Thread ID {1} , Start WriteSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_write1.GetHashCode()); Task t_write2 = new Task(WriteSomething); t_write2.Start(); Console.WriteLine("{0} Create Thread ID {1} , Start WriteSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_write2.GetHashCode()); //当某个线程进入读取模式时,此时其他线程依然能进入读取模式,假设此时一个线程要进入写入模式,那么他不得不被阻塞。直到读取模式退出为止。 Task t_read1 = new Task(ReadSomething); t_read1.Start(); Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read1.GetHashCode()); Task t_read2 = new Task(ReadSomething); t_read2.Start(); Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read2.GetHashCode()); Console.ReadKey(); } static public void ReadSomething() { Console.WriteLine("*************************************读取模式*********************************************"); Console.WriteLine("{0} Thread ID {1} Begin EnterReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); rwl.EnterReadLock();//进入读取模式锁定状态 try { Console.WriteLine("{0} Thread ID {1} reading sth...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); Thread.Sleep(5000);//模拟读取信息 Console.WriteLine("{0} Thread ID {1} reading end.", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); } finally { rwl.ExitReadLock(); Console.WriteLine("{0} Thread ID {1} ExitReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); } } static public void WriteSomething() { Console.WriteLine("***********************************写入模式***************************************************"); Console.WriteLine("{0} Thread ID {1} Begin EnterWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); rwl.EnterWriteLock();//进入写入模式锁定状态 try { Console.WriteLine("{0} Thread ID {1} writing sth...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); Thread.Sleep(10000);//模拟写入信息 Console.WriteLine("{0} Thread ID {1} writing end.", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); } finally { rwl.ExitWriteLock(); Console.WriteLine("{0} Thread ID {1} ExitWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Task.CurrentId.GetHashCode()); } } } }
输出结果如下:
02:29:04 442 Create Thread ID 59835590 , Start WriteSomething 02:29:04 458 Create Thread ID 66433212 , Start WriteSomething 02:29:04 458 Create Thread ID 42109742 , Start ReadSomething 02:29:04 458 Create Thread ID 14556615 , Start ReadSomething ***********************************写入模式*************************************************** 02:29:04 459 Thread ID 2 Begin EnterWriteLock... 02:29:04 459 Thread ID 2 writing sth... *************************************读取模式********************************************* 02:29:04 462 Thread ID 3 Begin EnterReadLock... *************************************读取模式********************************************* 02:29:04 465 Thread ID 4 Begin EnterReadLock... ***********************************写入模式*************************************************** 02:29:04 469 Thread ID 1 Begin EnterWriteLock... 02:29:14 462 Thread ID 2 writing end. 02:29:14 462 Thread ID 2 ExitWriteLock... 02:29:14 462 Thread ID 1 writing sth... 02:29:24 463 Thread ID 1 writing end. 02:29:24 463 Thread ID 1 ExitWriteLock... 02:29:24 463 Thread ID 4 reading sth... 02:29:24 463 Thread ID 3 reading sth... 02:29:29 464 Thread ID 4 reading end. 02:29:29 464 Thread ID 4 ExitReadLock... 02:29:29 464 Thread ID 3 reading end. 02:29:29 464 Thread ID 3 ExitReadLock...
发现2号写线程结束后(经过10s),1号写线程才进入写任务,1号线程执行10s后,3号和4号同时执行读任务。