Search code examples
javamultithreadingthread-synchronization

Printing Even and Odd numbers using 2 different classes


This was a question asked in one of my job interviews:

You have 2 different classes (that implements Runnable) say EvenThread & OddThread. As the name suggests, the EvenThread prints only even numbers and the odd thread prints only odd numbers, consider a range of 0-100.

class EvenThread implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i <= 10; i += 2) {
            System.out.println(i);
        }
    }
}

class OddThread implements Runnable {

    @Override
    public void run() {
        for (int i = 1; i < 10; i += 2) {
            System.out.println(i);
        }
    }
}

public class EvenOdd {

    public static void main(String args[]) {
        Thread tEven = new Thread(new EvenThread());
        Thread tOdd = new Thread(new OddThread());

        tEven.start();
        tOdd.start();
    }
}

Now we need to enforce a mechanism in such a way that, the numbers are printed in sequence (i.e. 0, 1, 2, 3, 4,.... and so on).

I have seen many similar questions in Stack Overflow, but they have just one class to print number and 2 synchronized methods are invoked in it.

Could any of the experts please suggest?


Solution

  • Here's an ugly example with a low-level-ish wait/notify mechanism:

    public class Main {
        static boolean turn = false; // false is even, true is odd
    
        public static void main(String[] args) {
            Object o = new Object();
            Thread tEven = new Thread(new EvenThread(o));
            Thread tOdd = new Thread(new OddThread(o));
    
            tEven.start();
            tOdd.start();
        }
    
        // TODO some inheritance with [Even/Odd]Thread
    
        static class EvenThread implements Runnable {
            Object o;
    
            EvenThread(Object o) {
                this.o = o;
            }
    
            @Override
            public void run() {
                for (int i = 0; i <= 10; i += 2) {
                    synchronized (o) {
                        try {
                            while (turn) {
                                o.wait();
                            }
                        }
                        catch (InterruptedException ie) {
                            ie.printStackTrace();
                        }
                        finally {
                            System.out.println(i);
                            turn = !turn;
                            o.notifyAll();
                        }
                    }
                }
            }
        }
    
        static class OddThread implements Runnable {
            Object o;
    
            OddThread(Object o) {
                this.o = o;
            }
    
            @Override
            public void run() {
                for (int i = 1; i < 10; i += 2) {
                    synchronized (o) {
                        try {
                            while (!turn) {
                                o.wait();
                            }
                        }
                        catch (InterruptedException ie) {
                            ie.printStackTrace();
                        }
                        finally {
                            System.out.println(i);
                            turn = !turn;
                            o.notifyAll();
                        }
                    }
                }
            }
        }
    }
    

    Output

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10