Print Even-Odd series with semaphores
We have already solved this problem in
this blog
with the use of synchronized, wait() and notify(). Letβs solve this with
semaphores. But before diving in, lets understand what actually is a
semaphore.
Semaphore
By definition, a semaphore is simply a variable that is non-negative and
shared between threads. A semaphore is a signalling mechanism, and a thread
that is waiting on a semaphore can be signalled by another thread. More about
semaphores is found
here.
Approach to the problem
Here we use semaphores to achieve the thread synchronization. While thread
one prints odd number, thread two should wait and vice-versa. This will go
until the loop ends.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SemaphoreControl { | |
public static void main(String[] args) { | |
SharedPrinter sharedPrinter = new SharedPrinter(); | |
Thread oddThread = new Thread(new Task(sharedPrinter, false), " Odd thread"); | |
Thread evenThread = new Thread(new Task(sharedPrinter, true), " Even Thread"); | |
oddThread.start(); | |
evenThread.start(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Task implements Runnable { | |
private SharedPrinter sharedPrinter; | |
private boolean isEven; | |
public Task(SharedPrinter sharedPrinter, boolean isEven) { | |
this.sharedPrinter = sharedPrinter; | |
this.isEven = isEven; | |
} | |
@Override | |
public void run() { | |
int number = isEven ? 2 : 1; | |
while (number <= 10) { | |
sharedPrinter.printNumber(number, isEven); | |
number += 2; | |
} | |
} | |
} |
We donβt have a isTurn variable to decide which thread should print
the number like in this blog instead we have two semaphores β odd and even.
Conceptually, semaphore maintains a set of permits. Here, we are giving the
odd thread a kick start by giving it a permit.
Now, we need to understand what are acquire() and release() method in
Semaphore.
acquire() method blocks if a permit is not available, else it allows
by reducing the available permits by one.
release() method adds a permit to the semaphore.
Here, when odd semaphore calls acquire() method, since it already have a
permit, the thread will not be blocked and prints the odd number.
At same time, when even thread calls acquire() method, it will be blocked as
it doesnβt have any permit. When, odd thread finishes printing, it will add
a permit to even semaphore which will give access to even thread to print.
After even thread finishes printing, it will give access to odd thread and
the same continues till the end of loop.
Post a Comment