Multithreading in .NET is made simpler. Reason behind the simplicity is the effective methods designed for thread communication. Monitor class supplies the following methods which are key in thread communication. They areWait (), Pulse (), PulseAll ().

 

Detailed Analysis

 

The Wait( ), Pulse( ), and PulseAll( ) methods are defined by the Monitor class. These methods can be called only from within a locked block of code. Here is how they are used. When a thread is temporarily blocked from running, it calls Wait( ).

 

This causes the thread to go to sleep and the lock for that object to be released, allowing another thread to use the object. At a later point, the sleeping thread is awakened when some other thread enters the same lock and calls Pulse( ) or PulseAll( ).

 

A call to Pulse( ) resumes the first thread in the queue of threads waiting for the lock.  A call to PulseAll( ) signals the release of the lock to all waiting threads.

 

Commonly used form of Wait() are

 

public static bool Wait(object waitOb)
public static bool Wait(object waitOb, int milliseconds)

 

Where waitOb is the object getting released.

 

Code Sample - Illustration

 

using System;

using System.Threading;

   

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(new ThreadStart(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");

  }

}

Code - Output

Tick Tock
Tick Tock
Tick Tock
Tick Tock
Tick Tock
Clock Stopped

 

Dead Lock

 

Deadlock is, as the name implies, a situation in which one thread is waiting for another thread to do something, but that other thread is waiting on the first. Thus, both threads are suspended, waiting for each other, and neither executes. This situation is analogous to two overly polite people both insisting that the other step through a door first!

 

Avoiding deadlock seems easy, but it's not. For example, deadlock can occur in roundabout ways. Consider the TickTock class. As explained, if a final Pulse( ) is not executed by tick( ) or tock( ), then one or the other will be waiting indefinitely and the program is deadlocked. Often the cause of the deadlock is not readily understood just by looking at the source code to the program, because concurrently executing threads can interact in complex ways.

 

Happy Learning !

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish