Use ReaderWriterLockSlim to create a thread-safe mechanism to read and write to a collection in multiple threads. ReaderWriterLockSlim represents a lock that manages access to a resource, allowing multiple threads to read concurrently, as well as exclusive writes.
Code Demo:
Using System;
Using System.Threading;
Using System.Collections.Generic;
Add the following code snippet below the Main method:
static ReaderWriterLockSlim _RW = new ReaderWriterLockSlim ();
Static Dictionary<int, int> _items = new Dictionary<int, int> ();
static void Read ()
{
Console.WriteLine ("Reading contents of a dictionary");
while (true)
{
Try
{
_RW. EnterReadLock ();
foreach (Var key in _items. Keys)
{
Thread.Sleep (Timespan.fromseconds (0.1));
}
}
Finally
{
_RW. Exitreadlock ();
}
}
}
static void Write (String threadname)
{
while (true)
{
Try
{
int newKey = new Random (). Next (250);
_RW. Enterupgradeablereadlock ();
if (!_items. ContainsKey (NewKey))
{
Try
{
_RW. Enterwritelock ();
_items[newkey] = 1;
Console.WriteLine ("New key {0} is added to a dictionary by a {1}", NewKey, ThreadName);
}
Finally
{
_RW. Exitwritelock ();
}
}
Thread.Sleep (Timespan.fromseconds (0.1));
}
Finally
{
_RW. Exitupgradeablereadlock ();
}
}
}
Add the following code snippet to the Main method:
New Thread (Read) {IsBackground = true}. Start ();
New Thread (Read) {IsBackground = true}. Start ();
New Thread (Read) {IsBackground = true}. Start ();
New Thread (() = Write ("Thread 1")) {IsBackground = true}. Start ();
New Thread (() = Write ("Thread 2")) {IsBackground = true}. Start ();
Thread.Sleep (Timespan.fromseconds (30));
Working principle
When the main program starts, three threads are running concurrently to read the data from the dictionary, and another two thread writes the data to the dictionary. We use the ReaderWriterLockSlim class to implement thread safety, and this class is designed to be a scenario like this.
Two types of locks are used here: Read locks allow multithreading to read data, and write locks block all operations of other threads before being released. There is also a scene when acquiring a read lock, that is, when reading data from the collection, determines whether to acquire a write lock and modify the collection based on the current data. Once a write lock is obtained, the reader is prevented from reading the data, wasting a lot of time, so the collection is blocked when the write lock is acquired. To minimize the time wasted by blocking, you can use the Enterupgradeablereadlock and Exitupgradeablereadlock methods. Reads the data after the read lock is acquired. If you find that you must modify the underlying collection, simply use the Enterlock method to upgrade the lock, then perform a write operation quickly, and finally use Exitwritelock to release the write lock.
In this case, our husband becomes a random number. It then acquires a read lock and checks to see if the number exists in the dictionary's key collection. If it does not exist, update the read lock to a write lock and then type the lock new key into the dictionary. It is a good practice to always use the Try/finaly code block to ensure that locks are released after capture.
All threads are created as background threads. The main thread waits 30 seconds after all background threads have completed.
Thread synchronization-using the ReaderWriterLockSlim class