Monday, December 28, 2015

Thread Interaction using wait and notify- Producer and Consumer


Wait() method can be used for multithread-synchronization i.e. wait() method is used for inter-thread communication.

When wait() called, Current thread relinquishes the lock and give to another Thread and comes into play when another thread notify the current thread to continue

A wait can be "woken up" by another thread calling notify on the monitor which is being waited on whereas a sleep cannot. Also a wait (and notify) must happen in a block synchronized on the monitor object whereas sleep does not:

Object mon = ...;
synchronized (mon) {
    mon.wait();
}

At this point the currently executing thread waits and releases the monitor. Another thread may do

synchronized (mon) { mon.notify(); }

(On the same mon object) and the first thread (assuming it is the only thread waiting on the monitor) will wake up.

public class ProducerConsumerWN {
    public static void main(String[] args) throws InterruptedException {
        
          final Processor1 processor=new Processor1();
          Thread t1 = new Thread(new Runnable() {
               @Override
               public void run() {
                    try {
                          processor.producer();
                    } catch (InterruptedException e) {
                          e.printStackTrace();
                    }
               }

          });

          Thread t2 = new Thread(new Runnable() {
               @Override
               public void run() {
                    try {
                          processor.consumer();
                    } catch (InterruptedException e) {
                          e.printStackTrace();
                    }
               }

          });
          t1.start();
          t2.start();
          t1.join();
          t2.join();
    }
}

class Processor1 {
     public void producer() throws InterruptedException {
        synchronized (this) {
             System.out.println("Lock acquired by" + Thread.currentThread().getName());
             System.out.println("Producer Thread running");
             this.wait();
             System.out.println("Resumed");
             System.out.println("Lock released by" + Thread.currentThread().getName());
        }
  }
     public void consumer() throws InterruptedException {
        Scanner scan = new Scanner(System.in);
        Thread.sleep(2000);
        synchronized (this) {
             System.out.println("Lock acquired by"+ Thread.currentThread().getName());
             System.out.println("Waiting for return hit");
             scan.nextLine();
             this.notify();
             System.out.println("Lock released by" + Thread.currentThread().getName());
             Thread.sleep(5000);
        }
  }
}

Output:
Lock acquired byThread-0
Producer Thread running
Lock acquired byThread-1
Waiting for return hit

Lock released byThread-1
5 sec wait
Resumed
Lock released byThread-0


EXAMPLE 2- WHERE RESULT PRINTS ONLY WHEN CALCULATION COMPLETES



package com.java5.executor;

public class Calculation {

     public static void main(String[] args) throws InterruptedException {
           ThreadA threadA = new ThreadA();
           threadA.start();
           /*we need to put a lock here and wake up only when
            * below calculation completes than means below thread
            * notify*/
           synchronized(threadA) {
                System.out.println("Putting thread in wait so as to complete calculation");
                threadA.wait();
                System.out.println("Total is " + threadA.total);
           }
     }
}

class ThreadA extends Thread {
     long total=1;
     public void run() {
           synchronized(this){
           for (int i = 1; i < 20; i++) {
                total = total * i;
           }
           this.notify();
      }
     }
}


Output

Putting thread in wait so as to complete calculation

Total is 121645100408832000

References

http://howtodoinjava.com/core-java/multi-threading/how-to-work-with-wait-notify-and-notifyall-in-java/
http://javarevisited.blogspot.in/2013/12/inter-thread-communication-in-java-wait-notify-example.html

1 comment:

  1. Could use lamda instead of Annonymous class

    Thread t1 = new Thread(() -> processor.producer());
    Thread t2 = new Thread(() -> processor.consumer());

    ReplyDelete