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(); }}
}