The concept of a read-write lock is simple , Allow multiple threads to acquire read lock at the same time , But only one thread is allowed to acquire a write lock at the same time , So it's also called sharing - An exclusive lock .

In some cases , The number of times an object is read is much greater than the number of times it is modified , If it's just a simple use lock Way lock , Will affect the efficiency of reading . And if you use a read-write lock , Multiple threads can read the object at the same time , Only when the object is occupied by the write lock , Will block .

To put it simply , When a thread enters read mode , At this point, other threads can still enter read mode , Suppose a thread wants to enter write mode , Then he had to be blocked . Until read mode exits .

alike , If a thread enters write mode , So other threads, whether they want to write or read , It's all going to be blocked .

Enter write / The read modes are 2 Methods :

EnterReadLock Try to enter the write mode lock state .

TryEnterReadLock(Int32) Try to enter the read mode lock state , You can choose an integer timeout .

EnterWriteLock Try to enter the write mode lock state .

TryEnterWriteLock(Int32) Try to enter the write mode lock state , You can choose the timeout .

Exit write / The read modes are 2 Methods :

ExitReadLock Reduce the recursive count of read mode , And when the generated count is 0( zero ) Exit read mode when .

ExitWriteLock Reduce the recursive count of write mode , And when the generated count is 0( zero ) Exit write mode when .

Let's demonstrate the usage :

 Thread t_read1 = new Thread(new ThreadStart(ReadSomething));
t_read1.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read1.GetHashCode());
Thread t_read2 = new Thread(new ThreadStart(ReadSomething));
t_read2.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read2.GetHashCode());
Thread t_write1 = new Thread(new ThreadStart(WriteSomething));
t_write1.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start WriteSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_write1.GetHashCode());
 static public void ReadSomething()
{
Console.WriteLine("{0} Thread ID {1} Begin EnterReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
rwl.EnterReadLock();
try
{
Console.WriteLine("{0} Thread ID {1} reading sth...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
Thread.Sleep();// Simulate reading information
Console.WriteLine("{0} Thread ID {1} reading end.", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
}
finally
{
rwl.ExitReadLock();
Console.WriteLine("{0} Thread ID {1} ExitReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
}
}
static public void WriteSomething()
{
Console.WriteLine("{0} Thread ID {1} Begin EnterWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
rwl.EnterWriteLock();
try
{
Console.WriteLine("{0} Thread ID {1} writing sth...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
Thread.Sleep();// Analog write information
Console.WriteLine("{0} Thread ID {1} writing end.", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
}
finally
{
rwl.ExitWriteLock();
Console.WriteLine("{0} Thread ID {1} ExitWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
}
}

stay 12 When thread No.1 turns on write mode ,10 Thread number and 11 The read mode of thread number is still running , After that 5 Seconds later , Read mode is over ,12 No. 1 thread just started writing mode ;

Modify the above code , First open 2 A write mode thread , Then turn on the read mode thread , The code is as follows :

 Thread t_write1 = new Thread(new ThreadStart(WriteSomething));
t_write1.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start WriteSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_write1.GetHashCode());
Thread t_write2 = new Thread(new ThreadStart(WriteSomething));
t_write2.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start WriteSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_write2.GetHashCode());
Thread t_read1 = new Thread(new ThreadStart(ReadSomething));
t_read1.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read1.GetHashCode());
Thread t_read2 = new Thread(new ThreadStart(ReadSomething));
t_read2.Start();
Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read2.GetHashCode());

You can see 9 Thread number and 10 Thread No. 2 turns on write mode at the same time , but 9 Thread number one starts first , We have to wait until 9 After the end of thread number ,10 No thread can start write mode , And read mode has to be 10 After the end of thread number ,11 and 12 No. 1 thread can read at the same time ;

TryEnterReadLock and TryEnterWriteLock You can set a timeout , When it comes to this sentence , Threads will block here , If the lock can be occupied at this time , Then the return true, If the lock has not been occupied by the timeout period , Then the return false, Relinquish lock occupancy , Just go ahead and execute the following code .

EnterUpgradeableReadLock

ReaderWriterLockSlim Class provides a scalable read mode , The difference between this mode and read mode is that it also calls EnterWriteLock or TryEnterWriteLock Method to write mode . Because only one thread can be in upgradable mode at a time . The thread that goes into upgradeable mode , Does not affect threads in read mode , That is, when a thread goes into upgradable mode , Any number of threads can enter read mode at the same time , It won't block . If more than one thread is already waiting to acquire a write lock , So run EnterUpgradeableReadLock Will block , Until those threads time out or exit the write lock .

The following code demonstrates how to do this in upgradeable read mode , Upgrade to write lock .

 static public void UpgradeableRead()
{
Console.WriteLine("{0} Thread ID {1} Begin EnterUpgradeableReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
rwl.EnterUpgradeableReadLock();
try
{
Console.WriteLine("{0} Thread ID {1} doing sth...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
Console.WriteLine("{0} Thread ID {1} Begin EnterWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
rwl.EnterWriteLock();
try
{
Console.WriteLine("{0} Thread ID {1} writing sth...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
Thread.Sleep();// Analog write information
Console.WriteLine("{0} Thread ID {1} writing end.", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
}
finally
{
rwl.ExitWriteLock();
Console.WriteLine("{0} Thread ID {1} ExitWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
}
Thread.Sleep();// Simulate reading information
Console.WriteLine("{0} Thread ID {1} doing end.", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
}
finally
{
rwl.ExitUpgradeableReadLock();
Console.WriteLine("{0} Thread ID {1} ExitUpgradeableReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
}
}
 static private object _lock1 = new object();
static public void ReadSomething_lock()
{
lock (_lock1)
{
//Console.WriteLine("{0} Thread ID {1} reading sth...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
Thread.Sleep();// Simulate reading information
//Console.WriteLine("{0} Thread ID {1} reading end.", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
}
}
static public void WriteSomething_lock()
{
lock (_lock1)
{
//Console.WriteLine("{0} Thread ID {1} writing sth...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
Thread.Sleep();// Analog write information
//Console.WriteLine("{0} Thread ID {1} writing end.", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
}
}
static public void ReadSomething()
{
rwl.EnterReadLock();
try
{
//Console.WriteLine("{0} Thread ID {1} reading sth...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
Thread.Sleep();// Simulate reading information
//Console.WriteLine("{0} Thread ID {1} reading end.", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
}
finally
{
rwl.ExitReadLock();
}
}
static public void WriteSomething()
{
rwl.EnterWriteLock();
try
{
//Console.WriteLine("{0} Thread ID {1} writing sth...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
Thread.Sleep();// Analog write information
//Console.WriteLine("{0} Thread ID {1} writing end.", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
}
finally
{
rwl.ExitWriteLock();
}
}

Test code :

 Stopwatch sw = new Stopwatch();
sw.Start();
List<Task> lstTask = new List<Task>();
for (int i = ; i < ; i++)
{
if (i % != )
{
var t = Task.Factory.StartNew(ReadSomething);
lstTask.Add(t);
}
else
{
var t = Task.Factory.StartNew(WriteSomething);
lstTask.Add(t);
}
}
Task.WaitAll(lstTask.ToArray());
sw.Stop();
Console.WriteLine(" Use ReaderWriterLockSlim The way , Time consuming :" + sw.Elapsed);
sw.Restart();
lstTask = new List<Task>();
for (int i = ; i < ; i++)
{
if (i % != )
{
var t = Task.Factory.StartNew(ReadSomething_lock);
lstTask.Add(t);
}
else
{
var t = Task.Factory.StartNew(WriteSomething_lock);
lstTask.Add(t);
}
}
Task.WaitAll(lstTask.ToArray());
sw.Stop();
Console.WriteLine(" Use lock The way , Time consuming :" + sw.Elapsed);

The above code , Just 500 individual Task, Every Task Occupy a thread pool thread , among 20 Write threads and 480 Read threads , Simulation operation . It takes... To read data 10ms, Write operations take 100ms, We have tested for lock The way and ReaderWriterLockSlim The way . You can make an estimate , about ReaderWriterLockSlim, hypothesis 480 Threads reading at the same time , So consumption 10ms,20 Write operations occupy 2000ms, So the time consumed 2010ms, And for ordinary lock The way , Because it's all exclusive , therefore 480 Read operations take up time 4800ms+20 Write operations 2000ms=6800ms. The running results show that the performance is improved obviously .

also ReaderWriterLockSlim Encapsulation :

http://www.cnblogs.com/blqw/p/3475734.html

example demo

http://files.cnblogs.com/files/xchit/Thread_example.rar

Read-write lock ReaderWriterLockSlim More articles about

  1. C# Read-write lock ReaderWriterLockSlim Use

    The concept of a read-write lock is simple , Allow multiple threads to acquire read lock at the same time , But only one thread is allowed to acquire a write lock at the same time , So it's also called sharing - An exclusive lock . stay C# in , Recommended ReaderWriterLockSlim Class to complete the function of read-write lock . In some cases , Yes ...

  2. Give Way C# Easy to separate read and write locks -- encapsulation ReaderWriterLockSlim

    ReaderWriterLockSlim class Represents the locked state used to manage resource access , It can realize multi thread read or exclusive write access . Use  ReaderWriterLockSlim  To protect read by multiple threads, but only one at a time ...

  3. Give Way C# Easy to separate read and write locks

    ReaderWriterLockSlim class Represents the locked state used to manage resource access , It can realize multi thread read or exclusive write access . Use ReaderWriterLockSlim To protect read by multiple threads, but only one at a time ...

  4. Using read-write lock three sentence code to solve multithreading concurrent writing file z

    C# Use read-write lock three code simple solution multithread concurrent write file prompt “ The file is being used by another process , As a result, the process cannot access this file ” The problem of In the process of developing the program , It's hard to avoid the key function of writing error log . Implement this function , You can choose to use the third ...

  5. The encapsulation of the lock Read-write lock 、lock

    Recently, it is suggested to use read-write lock on the project , And get rid of the common lock lock . Then it encapsulates the next lock according to the requirements . To simplify the use of locks . But development C# We all know lock Keywords are so convenient to use , however lock Keyword does not support timeout processing . Very helpless , In order to achieve ...

  6. C# Use read-write lock three lines of code to simply solve the problem of thread synchronization when multithreading writes files concurrently

    ( Add : initialization FileStream Include file share properties when using (System.IO.FileShare) Is more secure and efficient than using custom thread locks , More information can be found at ) In the process of developing the program , Writing errors are inevitable ...

  7. C# Prevent calling at the same time ========= Use read-write lock three lines of code to simply solve the problem of multithreading concurrency

    http://www.jb51.net/article/99718.htm     This paper mainly introduces C# Use read-write lock three lines of code to simply solve the problem of prompt when multithreading writes files concurrently " The file is being used by another process , As a result, the process has no problems ...

  8. C# Use read-write lock to solve the problem of thread synchronization when multithreads write files concurrently

    Read write lock is based on  ReaderWriterLockSlim  Object as a lock to manage resources , Different ReaderWriterLockSlim Locking the same file in an object is also managed as a different lock , This difference can lead to files again ...

  9. C# lock Grammar sugar implementation principle --《.NET Core Introduction to the bottom 》 Spin lock of , The mutex , Hybrid lock , Read-write lock

    In a multithreaded environment , Multiple threads may access the same resource at the same time , To avoid access conflicts , Different measures can be taken depending on the complexity of the visit Atomic operation is suitable for simple single operation , Lock free algorithm is suitable for relatively simple series of operations , Thread lock is suitable for complex one-way connection ...

Random recommendation

  1. Oracel_ Subquery

    SQL Subquery Subquery Syntax SELECT select_list FROM table WHERE expr operator (SELECT select_list FROM table) Subquery ( ...

  2. Sublime Text 3 Chinese skills

    Sublime Text 3 How to use simplified Chinese package 1. Will download sublime_text3 Decompress the Chinese package file , Got Default.sublime-package file . open sublime text 3 ...

  3. 1010 Every time I back up my MySQL database

    from http://bbs.csdn.net/topics/320136534 stay windows Under the platform /*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/* ...

  4. List Operation of the Select

    This article is for C# Novice , Don't be a veteran , It's actually about LINQ, Thanks for the reminder on the first floor . A lot of times , Pick out a list of elements we need from a relational table and use SQL The sentence can't be easier , Actually C# Of List A similar approach can also be used in , ...

  5. 【 Alibaba cloud product beta 】 Cloud engine ACE -discuz install

    author : Alibaba cloud users want the future Thank you for your support . Why write is relatively simple is for the convenience of novices who want to be very troublesome ? Press this tutorial to install successfully ! Time is running out. No more pictures. It's just original Please understand the typesetting Enter the information filling interface for creating a new application , Here you need to fill in a gift ...

  6. 【 original 】alias And export

    Recently in to see lualua dependent , among k There is os.getenv('kroot'), notice ~/.bashrc reason kroot But why not get , It turns out that it's written as alias 了 , Should be export Of . alias rer ...

  7. Page Jump url How to write the address

    Jump address : There are two kinds ,wikipage and aspx page : wikipage: When new webpart, Create a new one in the website wikipage, And then webpart Added to the wikipage, In this case, the jump page needs to add si ...

  8. lnmp Under the architecture php Security configuration sharing

    Catalog [-] 1. Use open_basedir Restrict virtual host cross Directory Access 2. It's not safe to disable PHP function 3. Focus on software security information 4. php Users read only 5. close php Error log 6. php Upload separation 7. Turn off ...

  9. WebSphere Several methods of performance optimization

    1. change http server Configuration file parameters for KeepAlive.      reason : This value indicates whether to keep the customer and HTTP SERVER The connection of , If set to ON, Then the number of requests arrives MaxKeepAliveRequest ...

  10. Trees -- AVL Trees

    Preface Through the previous discussion on binary search tree , We know that for a given number of nodes , The lower the height of the binary tree , The less time it takes to find . When we talk about the red black tree , We said that the red black tree is not completely " Balance " Two fork tree , Just approximate &q ...