In this blog post, we will explore another set of simple functions and demonstrate how to synchronize them to achieve consistent results using semaphores.
The class provides 3 methods
Prints 0s
Prints odd numbers
Prints even numbers
The solution using semaphores:
package com.example;
import lombok.SneakyThrows;
import java.util.concurrent.Semaphore;
public class PrintNumber {
private final int num;
private final Semaphore zeroSem;
private final Semaphore oddSem;
private final Semaphore evenSem;
public PrintNumber(int num) {
this.num = num;
// this semaphore can allocate 1 permit at a time for threads in the waiting queue
zeroSem = new Semaphore(1);
oddSem = new Semaphore(0);
evenSem = new Semaphore(0);
}
@SneakyThrows
public void printZero() {
for (int i = 0; i < this.num; i++) {
// thread acquires the single permit from zero Semaphore
zeroSem.acquire();
System.out.println("0");
// one permit is released to one of the other two semaphores
(i % 2 == 0 ? oddSem : evenSem).release();
}
}
@SneakyThrows
public void printOdd() {
for (int i = 1; i <= this.num; i += 2) {
oddSem.acquire();
System.out.println(i);
// after having printed the odd number, 0 should be printed so pass the permit back to zero Semaphore
zeroSem.release();
}
}
@SneakyThrows
public void printEven() {
for (int i = 2; i <= this.num; i += 2) {
evenSem.acquire();
System.out.println(i);
// after having printed the even number, 0 should be printed so pass the permit back to zero Semaphore
zeroSem.release();
}
}
}
There are further examples of how to use Java’s monitor to achieve synchronized thread execution:
Crafting Thread-Safe Functions in Java - Part 1