Printing Even and Odd numbers using 2 different classes Printing Even and Odd numbers using 2 different classes multithreading multithreading

Printing Even and Odd numbers using 2 different classes


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

012345678910


Not a direct answer to your question but just to show you do not always need locks or synchronization - a memory barrier could suffice.

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;public class EvenAndOdd implements Runnable {public static final int MAX_RUNTIME_SECONDS = 3;public static void main(String[] args) {    ExecutorService tp = Executors.newCachedThreadPool();    AtomicInteger counter = new AtomicInteger();    tp.execute(new EvenAndOdd(counter, true));    //try { Thread.sleep(500); } catch (Exception ignored) {}    tp.execute(new EvenAndOdd(counter, false));    tp.shutdown();    boolean tpTerminated = false;    try {        if (tp.awaitTermination(MAX_RUNTIME_SECONDS, TimeUnit.SECONDS)) {            tpTerminated = true;            System.out.println("Finished.");        }    } catch (Exception e) {        e.printStackTrace();    } finally {        if (!tpTerminated) {            System.out.println("Forcing shutdown.");            tp.shutdownNow();        }    }}public static final int MAX_COUNTER = 10;private final boolean odd;private final AtomicInteger counter;public EvenAndOdd(AtomicInteger counter, boolean odd) {    this.odd = odd;    this.counter = counter;}@Overridepublic void run() {    int emptyCycleCounter = 0;    while (true) {        int i = counter.get();        if (i > MAX_COUNTER) {            break;        }        if (i % 2 == (odd ? 1 : 0)) {            System.out.println(i + (odd ? " odd" : " even"));            counter.incrementAndGet();        } else {            emptyCycleCounter++;            Thread.yield();        }    }    System.out.println("Finished"  + (odd ? " odd" : " even") + " with " + emptyCycleCounter + " empty cycles.");}}


public class MyLock {

public MyLock(Boolean even) {    super();    this.even = even;}static Boolean even = null;public synchronized void lock(boolean value) {    while (even != value) {        try {                    wait();        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}public synchronized void unlock() {    even = !even;    notify();}

}

public class OddEven {

private static final int Max_CCOUNTER = 100;static final MyLock lock = new MyLock(true);public static void main(String[] args) {    // TODO Auto-generated method stub    new Thread(() -> printEven(), "EVEN").start();    ;    new Thread(() -> printOdd(), "ODD").start();    ;}static void printEven() {    for (int i = 0; i < Max_CCOUNTER; i = i + 2) {        lock.lock(true);        System.out.println(i + ":" + Thread.currentThread().getName());        lock.unlock();    }}static void printOdd() {    for (int i = 1; i < Max_CCOUNTER; i = i + 2) {        lock.lock(false);        System.out.println(i + ":" + Thread.currentThread().getName());        lock.unlock();    }}

}