Threading with Monitor
A monitor is a mechanism for 
ensuring that only one thread at a time may be running a certain piece of code 
(critical section). A monitor has a lock, and only one thread at a time may 
acquire it. To run in certain blocks of code, a thread must have acquired the 
monitor. A monitor is always associated with a specific object and cannot be 
dissociated from or replaced within that object. 
Monitor has the following features: 
- It is associated with an object on demand.
 - 
It is unbound, which means it can be called directly from any context.
 - 
An instance of the Monitor class cannot be created.
 
The following information 
is maintained for each synchronized object: 
- A reference to the thread that currently holds the lock.
 - A reference to a ready queue, which contains the threads that are ready to obtain the lock.
 - A reference to a waiting queue, which contains the threads that are waiting for notification of a change in the state of the locked object. 
 
Monitor Class
The Monitor Class Provides a 
mechanism that synchronizes access to objects. The Monitor class is a collection 
of static methods that provides access to the monitor associated with a 
particular object, which is specified through the method's first argument. the 
class provide following method.
- Monitor.Enter() : Acquires an exclusive lock on the specified object. This action also marks the 
beginning of a critical section. 
 - Monitor.Exit() : Releases an exclusive lock on the specified object. This action also marks the 
end of a critical section protected by the locked                          object. 
 - Monitor.Pules() 
: Notifies a thread in the waiting queue of a change in the locked object's 
state. 
 - Monitor.Wait() : Releases the lock on an object and blocks the current thread until it 
reacquires the lock. 
 - Monitor.PulesAll() : Notifies all waiting threads of a change in the object's state. 
 - Monitor.TryEnter() 
: Attempts to acquire an exclusive lock on the specified object. 
 
In the following example we have three threads 
which are trying to write a file (akshay.txt). 
Basically each thread will wait until the locker object gets 
released by the first thread that achieved a lock, before it attempts to write 
to our file. 
using 
System;
using System.IO;
using 
System.Threading;
namespace 
monitorclass
{
class Program
    {
        static object 
locker = new object();
        static void 
ThreadMain()
        {          
             Thread.Sleep(800);    // Simulate Some work
             WriteToFile();           // Access a shared resource / critical 
section
        }
        static void 
WriteToFile()
        {
            String ThreadName =
Thread.CurrentThread.Name;
            Console.WriteLine("{0} 
using C-sharpcorner.com", ThreadName);
            Monitor.Enter(locker);
            try
            {
                using (StreamWriter 
sw = new 
StreamWriter(@"D:\akshaydata\akshay.txt",
true))
               {
                    sw.WriteLine(ThreadName);
                }
            }
            catch (Exception 
ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Monitor.Exit(locker);
                Console.WriteLine("{0} 
releasing C-sharpcorner.com", ThreadName);
            }
        }
        static void 
Main(string[] args)
        {
            for (int 
i = 0; i < 3; i++)
            {
                Thread thread =
new Thread(new
ThreadStart(ThreadMain));
                thread.Name = String.Concat("Thread 
- ", i);
                thread.Start();
                
            }
            Console.Read();
        }
    }
}
Output
![1.gif]()
Use Wait() and Pulse() to create a ticking clock
Monitor.Wait() 
is used to  Releases the lock on an object in 
order to permit other threads to lock and access the object. The calling thread 
waits while another thread accesses the object. Pulse signals are used to notify 
waiting threads about changes to an object's state. 
using 
System;
using 
System.Threading;
namespace 
waitndpulesmethod
{
class TickTock
    {
        public void 
tick(bool running)
        {
            lock (this)
            {
                if (!running)
                {  //  stop  the  clock    
                    Monitor.Pulse(this); 
//  notify  any  waiting  threads    
                    return;
                }
                Console.Write("Tick  ");
                Monitor.Pulse(this);  //  let  tock()  run    
                Monitor.Wait(this); 
//  wait  for  tock()  to  complete    
            }
        }
        public void 
tock(bool running)
        {
            lock (this)
            {
                if (!running)
                {  //  stop  the  clock    
                    Monitor.Pulse(this);  //  notify  any  waiting  
threads    |
                    return;
                }
                Console.WriteLine("Tock");
                Monitor.Pulse(this);  //  let  tick()  run    
                Monitor.Wait(this); 
//  wait  for  tick()  to  complete    
            }
        }
    }
    class MyThread
    {
        public 
Thread thrd;
        TickTock ttOb;
        //  Construct  a  new  thread.    
        public MyThread(string 
name, TickTock tt)
        {
            thrd = new
Thread(this.run);
            ttOb = tt;
            thrd.Name = name;
            thrd.Start();
        }
        //  Begin  execution  of  new  thread.    
        void run()
        {
            if (thrd.Name ==
"Tick")
            {
                for (int 
i = 0; i < 5; i++) ttOb.tick(true);
                ttOb.tick(false);
            }
            else
            {
                for (int 
i = 0; i < 5; i++) ttOb.tock(true);
                ttOb.tock(false);
            }
        }
    }
    class 
TickingClock
    {
        public static
void Main()
        {
            TickTock tt =
new TickTock();
            MyThread mt1 =
new MyThread("Tick", 
tt);
            MyThread mt2 =
new MyThread("Tock", 
tt);
 
            mt1.thrd.Join();
            mt2.thrd.Join();
            Console.WriteLine("Clock  
Stopped");
            Console.Read();
        }
    }  
}
Output
![2.gif]()
Monitor Pool
A thread pool is a collection of threads that can 
be used to perform a number of tasks in the background. Thread pools are often 
employed in server applications. Each incoming request is assigned to a thread 
from the thread pool. Once a thread in the pool completes its task, it is 
returned to a queue of waiting threads, where it can be reused. This reuse 
enables applications to avoid the cost of creating a new thread for each task.
using 
System;
using 
System.Threading;
namespace 
monitorpool
{
class Akshay
    {
        private const
int threads = 3;
        private const
int workitems = 20;
        private static
Object locker = new
Object();
        static void 
Worker()
        {
            while (true)
            {
                lock (locker)
                {
                    Monitor.Wait(locker);
                }
                System.Console.WriteLine("{0} 
access the website c-sharpcorner", Thread.CurrentThread.Name);
                Thread.Sleep(100);
           }
        }
        [STAThread]
        static void 
Main(string[] args)
        {
           Thread[] t =
new Thread[threads];
             for (int 
k = 0; k < threads; k++)
            {
               t[k] = new
Thread(new
ThreadStart(Worker));
                t[k].Name = "user " + k;
                t[k].IsBackground = true;
                t[k].Start();
            }
            for (int 
i = 0; i < workitems; i++)
            {
               Thread.Sleep(1000);
                 lock (locker)
                {
                    Monitor.Pulse(locker);
                }
            }
            Console.Read();
        }
    }
}
Output
![3.gif]()