import java.util.concurrent.Semaphore;
import java.util.function.IntConsumer;
public class ZeroEvenOdd {
private int n, lastPrinted;
private Semaphore oddSem;
private Semaphore zeroSem;
private Semaphore evenSem;
public ZeroEvenOdd(int n) {
this.n = n;
this.lastPrinted = 0;
this.zeroSem = new Semaphore(1);
this.oddSem = new Semaphore(1);
this.evenSem = new Semaphore(1);
try {
this.evenSem.acquire();
this.oddSem.acquire();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void zero(IntConsumer printNumber) throws InterruptedException {
int numZeros = n;
while (numZeros-- > 0) {
this.zeroSem.acquire();
printNumber.accept(0);
if (lastPrinted % 2 == 0) {
this.oddSem.release();
} else {
this.evenSem.release();
}
}
}
public void even(IntConsumer printNumber) throws InterruptedException {
int numeven = n / 2;
while (numeven-- > 0) {
this.evenSem.acquire();
printNumber.accept(++lastPrinted);
this.zeroSem.release();
}
}
public void odd(IntConsumer printNumber) throws InterruptedException {
int numOdd = n - n / 2;
while (numOdd-- > 0) {
this.oddSem.acquire();
printNumber.accept(++lastPrinted);
this.zeroSem.release();
}
}
public static void main(String[] args) {
ZeroEvenOdd print = new ZeroEvenOdd(5);
Thread thread = new Thread() {
public void run() {
System.out.println("Thread Running");
IntConsumer ic = (x) -> System.out.println(x);
try {
print.zero(ic);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread thread2 = new Thread() {
public void run() {
System.out.println("Thread Running");
IntConsumer ic = (x) -> System.out.println(x +"\t");
try {
print.odd(ic);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread thread3 = new Thread() {
public void run() {
System.out.println("Thread Running");
IntConsumer ic = (x) -> System.out.println(x);
try {
print.even(ic);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
thread.start();
thread2.start();
thread3.start();
}
}