INTERTHREAD COMMUNICATION WAIT AND NOTIFYALL METHOD

Interthread Communication wait and notfiyAll method


  • Interthread Communication wait and notfiall method: Multithreading replaces event loop programming by dividing your tasks into discreet and logical units. Threads also provide a secondary benefit: they do away with polling. Polling is usually implemented by a loop that is used to check some condition repeatedly. Once the condition is true, appropriate action is taken. This wastes CPU time.To avoid polling, Java includes an elegant inter-process communication via wait(), notify() and notifyAll(). These methods are implemented as final methods in Object, so all classes have them. All these three methods can be called only from within a synchronized method. .

  • The method wait() tells the calling thread to give up the monitor and go to sleep until some other thread enters the monitor and calls notify(). Additional forms of wait() exist that allow you to specify a period of time to wait. The method notify() wakes up the first thread that called wait() on the same object. The method notifyAll() wakes up all the threads that called wait() on the same object. The highest priority thread will run first.

  • Example 1:

    
                            
                      class MyEven extends Thread
                      {
                         MyOdd b;
                         public MyEven(MyOdd b)
                         {
                            this.b = b;   
                         }
                         public void run()
                         {
                            synchronized (b)
                            {
                               for(int i=0;i<=100;i+=2)
                               {
                                  System.out.println(getName()+" :"+i);
                                  try
                                  {
                                     b.wait();
                                     sleep(100);
                                  }
                                  catch(InterruptedException ex)
                                  {
                                     ex.printStackTrace();   
                                  }
                                  b.notifyAll();
                               }
                            }
                         }
                      }
                      class MyOdd extends Thread
                      {      
                         public void run()
                         {
                            synchronized (this)
                            {
                               for(int i=1;i<=100;i+=2)
                               {
                                  System.out.println(getName()+" :"+i);
                                  notifyAll();
                                  try
                                  {
                                     wait();       
                                  }
                                  catch(InterruptedException ex)
                                  {
                                     ex.printStackTrace();   
                                  }
                               }
                            }
                         }
                      }
                      public class EvenOddDemo
                      {
                         public static void main(String[] args)
                         {   
                            MyOdd odd = new MyOdd();
                            MyEven even = new MyEven(odd);
                            even.start();
                            odd.start();
                         }
                      }                    
    • Dead Lock

      If two threads keep on waiting for each other for resources is called “Dead Lock”.

    Example 2:

    
                            
                      package com.sdj.pack1;
                      class Share
                      {
                         synchronized void test1(Share s2)
                         {
                            System.out.println(Thread.currentThread().getName()+" in test1");
                            try
                            {
                               Thread.sleep(300);   
                            }
                            catch(InterruptedException e)
                            {
                               e.printStackTrace();
                            }
                            s2.test1(this);
                            System.out.println(Thread.currentThread().getName()+" finish test1");
                         }
                         synchronized void test2(Share s1)
                         {
                            System.out.println(Thread.currentThread().getName()+" in test2");
                            try
                            {
                               Thread.sleep(300);   
                            }
                            catch(InterruptedException e1)
                            {
                               e1.printStackTrace();   
                            }
                            s1.test1(this);
                            System.out.println(Thread.currentThread().getName()+" finish test2");
                         }
                      }
                      class ThShare extends Thread
                      {
                         Share s1,s2;
                         ThShare(Share s1,Share s2)
                         {
                            this.s1=s1;
                            this.s2=s2;
                         }
                         public void run()
                         {
                            System.out.println(getName()+" start");
                            s1.test1(s2);
                            System.out.println(getName()+" end");
                         }
                      }
                      class ThShare1 extends Thread
                      {
                         Share s1,s2;
                         ThShare1(Share s1,Share s2)
                         {
                            this.s1=s1;
                            this.s2=s2;
                         }
                         public void run()
                         {
                            System.out.println(getName()+" start");
                            s2.test2(s1);   
                         }
                      }
                      public class ThDeadLock 
                      {
                         public static void main(String[] args) 
                         {
                            Share s1=new Share();
                            Share s2=new Share();
                            ThShare t1=new ThShare(s1,s2);
                            ThShare1 t2=new ThShare1(s1,s2);
                            t1.start();
                            t2.start();
                            System.out.println("main end");
                         }
                      }
                                      

       Output:

    Thread 0 starts Thread 0 in test1 Go to sleep mode T2 is starts execution Thread 1 starts Thread 1 in test2 Go to sleep modeG T1 starts execution S2.test2(this) [ current usage object in test1() method i.e. s1 means t1.s1.test1(s2)] To execute test2(-) method thread 0 need s2 object lock but s2 lock is holded by thread1. So play idle role and go to runnable. T2 comes for execution then reach S1.test1(this) To run test1(--) method we need s1 object lock and this is hold by thread 0 So finally                         we get dead lock state