C#读写锁ReaderWriteLockSlim的使用

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号同时执行读任务。

 

C#读写锁ReaderWriteLockSlim的使用

上一篇:C# byte[]与Image类型互相转换


下一篇:WPF 简单使用keybd_event模拟触发键盘