Inter Thread communication



Inter Thread communication

Java provides three methods that threads can use to communicate with each other:

 public final void wait()throws InterruptedException

 public final native void notify(),

 public final native void notifyAll().

These methods are defined for all objects (not just Threads). The idea is that a method called by a thread may need to wait for some condition to be satisfied by another thread. In that case, it can call the wait method, which causes its thread to wait until another thread calls notify or notifyAll.

A call to notify causes at most one thread waiting on the same object to be notified (i.e., the object that calls notify must be the same as the object that called wait). A call to notifyAll causes all threads waiting on the same object to be notified. If more than one thread is waiting on that object, there is no way to control which of them is notified by a call to notify (so it is often better to use notifyAll than notify).

wait(long timeout)

public final native void wait(long timeout) throws InterruptedException

Causes the current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed.

“All three methods can be called only from within a synchronized context.”

The rules for using these methods are actually quite simple:

    wait() tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls notify().
    notify() wakes up the first thread that called wait() on the same object.
    notifyAll() wakes up all the thread that called wait() on the same object, The highest priority thread will run first.

public class Student {

String name=null;

synchronized String getName(){

    System.out.println("getName() called..");

    if(name==null)

    {

        try{

            wait();

        }catch(Exception e){}

    }

    System.out.println("Name "+name);

  //  name=null;

    return name;

}

synchronized void putName(String name){

    System.out.println("putName() called...");

    this.name=name;

    notify();//notifyAll() can be called

}

}

public class GetThread extends Thread {

    Student s;

    GetThread(Student s) {

        this.s = s;

    }

    @Override

    public void run() {

        String sname = s.getName();

        if (sname.equals("Raj")) {

            System.out.println("User:" + sname);

        } else {

            System.out.println("Guesst:" + sname);

        }

    }

}

public class PutThread extends Thread {

    Student s;

    PutThread(Student s) {

        this.s = s;

    }

    @Override

    public void run() {

        s.putName("Raj");

    }

}

public class StudentTest {

public static void main(String as[]){

    Student s=new Student();

    GetThread gt=new GetThread(s);

    PutThread pt=new PutThread(s);

    gt.start();

    pt.start();

   }

}

In above example GetThread is first of all started  and called student object’s getName() method, but name is null so suspended till PutThread which is also in queue for execution not set the name by calling setName() method, after PutThread set name call notify to wake up GetThread again and print name; It is also clear form above one thread call wait() on student object and other call notify on student object.

Other producer and consumer example:-

public class Q {

    int n;

    boolean valueSet = false;

    synchronized int get() {

        if (!valueSet) {

            try {

                wait();

            } catch (Exception e) {

                System.out.println(e);

            }

        }

        System.out.println("Got: " + n);

        valueSet = false;

        notify();

        return n;

    }

    synchronized void put(int n){

        if(valueSet){

            try{

                wait();

            }catch(Exception e){System.out.println(e);}

        }

        this.n=n;

        valueSet=true;

        System.out.println("Put: "+n);

        notify();

    }

}

public class Consumer implements Runnable {

    Q q;

    Consumer(Q q) {

        this.q = q;

        new Thread(this, "Consumer").start();

    }

    public void run() {

        while (true) {

            q.get();

        }

    }

}

public class Producer implements Runnable {

    Q q;

    Producer(Q q) {

        this.q = q;

        new Thread(this, "Producer").start();

    }

    public void run() {

        int i = 0;

        while (true) {

            q.put(i++);

        }

    }

}

public class PCFixed {

public static void main(String as[]){

    Q q=new Q();

    new Consumer(q);

    new Producer(q);



    System.out.println("Press Control-c to stop.");

}

}

No comments:

Post a Comment