Sunday, July 13, 2014

Concurrency: Using wait() and notifyAll() [Example Program][Java]

wait(), notify() and notifyAll() must only be placed within synchronized methods or blocks. sleep() can be called within non-synchronized methods. If you call any of these methods within a method that's not synchronized, the program will compile, but when you run it, you'll get an IllegalMonitorStateException.

1. The object lock is released during the wait().
2. You can also come out of the wait() due to a notify() or notifyAll(), or if the timeout occurs (using the
     timed version of wait    ->    wait(pause).

import java.util.concurrent.*;

class Runnable1 implements Runnable {

    public synchronized void waiter() {
        try {
            wait();
            System.out.println("Runnable1 notified!");
        } catch (InterruptedException ex) {
            System.out.println("Runnable1 interrupted! - Not notified!");
        }
    }

    @Override
    public void run() {
        waiter();
    }
}

class Runnable2 implements Runnable {

    Runnable1 ref;

    Runnable2(Runnable1 run) {
        ref = run;
    }

    public void notifier() {
        synchronized (ref) {
            ref.notifyAll();
        }
    }

    @Override
    public void run() {
        while (!Thread.interrupted()) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException ex) {
                System.out.println("Sleep interrupted!");
                break;
            }
             notifier();
        }
        System.out.println("Exiting Runnable2 run()");
    }

}

public class Ex21 {

    public static void main(String[] args) throws InterruptedException {
        ExecutorService exec = Executors.newCachedThreadPool();
        Runnable1 ref1 = new Runnable1();
        exec.execute(ref1);
        exec.execute(new Runnable2(ref1));
        TimeUnit.SECONDS.sleep(2);
        exec.shutdownNow();
        System.out.println("All tasks terminated!");
    }
}

Runnable1 first wait() s to get notified by Runnable2's notifier(). And then displays the message that
it was notified. But if timeout occurs (after calling shutdownNow() on the Executor) (3 seconds / change timeout values to see different ouput), Runnable1 displays the message that it wasn't notified.

Output:

If Runnable1 gets notified:

Runnable1 notified!
Sleep interrupted!
Exiting Runnable2 run()
All tasks terminated!

If it doesn't:

All tasks terminated!
Runnable1 interrupted! - Not notified!
Sleep interrupted!
Exiting Runnable2 run()










No comments:

Post a Comment