Browse DevX
Sign up for e-mail newsletters from DevX


Master Managed Threading and Synchronization Techniques : Page 6

Dive deep into the various synchronization techniques available in the .NET framework, including inter-thread and inter-process synchronization.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Read-Writer Locks
Read-Writer locks help in optimizing synchronization where you have more threads executing read operations than write operations. Read-Writer locks allow multiple read-only threads to enter the code, but allow only one writer thread at a time. You use the ReadWriterLockSlim class to implement Read-Writer locks.

Consider the code sample below, in which three threads try to acquire a read lock while one thread tries to acquire a writer lock. The writer thread is able to acquire the lock only after all the reader threads have released their locks. Similarly, a reader thread can acquire the lock only after the writer thread releases it. However, multiple reader threads can acquire read locks at the same time:

// Read-Writer Lock example namespace ThreadingInDotNet { class Program { static void Main(string[] args) { ThreadSafeType tst = new ThreadSafeType(); Thread t1 = new Thread(new ThreadStart(tst.GetValue)); Thread t2 = new Thread(new ThreadStart(tst.GetValue)); Thread t3 = new Thread(new ThreadStart(tst.Increment)); Thread t4 = new Thread(new ThreadStart(tst.GetValue)); t1.Start(); t2.Start(); t3.Start(); Thread.Sleep(500); t4.Start(); } } class ThreadSafeType { ReaderWriterLockSlim counterLock = new ReaderWriterLockSlim(); int counter = 0; public void Increment() { counterLock.EnterWriteLock(); Console.WriteLine(" In Writer Lock, Thread ID : " + Thread.CurrentThread.GetHashCode()); counter++; counterLock.ExitWriteLock(); Console.WriteLine(" Exited Writer Lock, Thread ID : " + Thread.CurrentThread.GetHashCode()); } public void GetValue() { counterLock.EnterReadLock(); Console.WriteLine("In Reader Lock, Thread ID : " + Thread.CurrentThread.GetHashCode()); Thread.Sleep(3000); Console.WriteLine("Thread ID : "+ Thread.CurrentThread.GetHashCode() + " Counter Value : " + counter); counterLock.ExitReadLock(); Console.WriteLine("Exited Reader Lock, Thread ID : " + Thread.CurrentThread.GetHashCode()); } } }

Running the preceding code produces the following output:

In Reader Lock, Thread ID : 3 In Reader Lock, Thread ID : 4 Thread ID : 3 Counter Value : 0 Exited Reader Lock, Thread ID : 3 Thread ID : 4 Counter Value : 0 Exited Reader Lock, Thread ID : 4 In Writer Lock, Thread ID : 5 Exited Writer Lock, Thread ID : 5 In Reader Lock, Thread ID : 6 Thread ID : 6 Counter Value : 1 Exited Reader Lock, Thread ID : 6

Semaphores control access to a resource or pool of resources by restricting the number of clients that an access the resource at any given moment. They can be either local or named system-wide. You use the System.Threading.Semaphore class to implement semaphores.

Semaphores do not enforce thread affinity. Threads enter the semaphore by calling the WaitOne method. The semaphore count is decremented each time a thread enters and incremented when the thread exits.

In the code sample below, five threads try to enter the code region, but the code restricts the maximum access count to three during the semaphore's construction:

// local Semaphore example class Program { static Semaphore sph; static void Main(string[] args) { sph = new Semaphore(3, 3); Thread th; for (int i = 0; i < 5; i++) { th = new Thread(new ThreadStart(PrintThreadId)); th.Start(); Thread.Sleep(1000); } } public static void PrintThreadId() { sph.WaitOne(); Console.WriteLine("Thread ID:{0} enters semaphore," Thread.CurrentThread.ManagedThreadId); Thread.Sleep(3000); Console.WriteLine("Thread ID:{0} exiting semaphore," Thread.CurrentThread.ManagedThreadId); sph.Release(); } }

Below is the output of the above code, which shows that the fourth thread (Thread ID 6) could enter the PrintThreadId method only after one of the first three threads exits the semaphore:

Thread ID:3 enters semaphore Thread ID:4 enters semaphore Thread ID:5 enters semaphore Thread ID:3 exiting semaphore Thread ID:6 enters semaphore Thread ID:4 exiting semaphore Thread ID:7 enters semaphore Thread ID:5 exiting semaphore Thread ID:6 exiting semaphore Thread ID:7 exiting semaphore

Thanks for your registration, follow us on our social networks to keep up-to-date