Engineering Full Stack Apps with Java and JavaScript
In computer science, particularly in operating systems, a semaphore is a variable or abstract data type that provides a simple but useful abstraction for controlling access, by multiple processes, to a common resource in a parallel programming or a multi user environment. Semaphores which allow an arbitrary resource count are called counting semaphores, while semaphores which are restricted to the values 0 and 1 (or locked/unlocked, unavailable/available) are called binary semaphores.
Counting semaphores control the number of activities that can access a certain resource or activity at the same time. They can be used to implement resource pools. A Semaphore manages a set of virtual permits to access a certain resource or activity. The initial number of permits is passed to the Semaphore constructor. Activities can acquire permits and release permits. If no permit is available, acquire blocks until one is available or until interrupted or the operation times out. The release method returns a permit to the semaphore. As binary semaphores are restricted to the values 0 and 1, they can be used for mutual exclusion; whoever holds the only permit can access the resource.
Counting Semaphore Example – SemaphoreDemo.java
import java.util.Date;
import java.util.concurrent.Semaphore;
public class SemaphoreDemo {
public void DemoSemaphore(int capacity) {
final Semaphore available = new Semaphore(capacity, true);
String name = "";
for (int i = 0; i < 5; i++) {
name = "MyThread-" + (i + 1);
new Thread(name) {
@Override
public void run() {
try {
available.acquire();
System.out.println("Started " + Thread.currentThread() + " at " + new Date());
Thread.sleep(5000);
System.out.println("Exiting " + Thread.currentThread() + " at " + new Date());
available.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
}
public static void main(String[] args) {
SemaphoreDemo sD = new SemaphoreDemo();
sD.DemoSemaphore(2);
}
}
Output
Started Thread[MyThread-1,5,main] at Mon Jul 08 11:01:39 IST 2013
Started Thread[MyThread-2,5,main] at Mon Jul 08 11:01:39 IST 2013
Exiting Thread[MyThread-2,5,main] at Mon Jul 08 11:01:44 IST 2013
Started Thread[MyThread-3,5,main] at Mon Jul 08 11:01:44 IST 2013
Exiting Thread[MyThread-1,5,main] at Mon Jul 08 11:01:44 IST 2013
Started Thread[MyThread-5,5,main] at Mon Jul 08 11:01:44 IST 2013
Exiting Thread[MyThread-5,5,main] at Mon Jul 08 11:01:49 IST 2013
Exiting Thread[MyThread-3,5,main] at Mon Jul 08 11:01:49 IST 2013
Started Thread[MyThread-4,5,main] at Mon Jul 08 11:01:49 IST 2013
Exiting Thread[MyThread-4,5,main] at Mon Jul 08 11:01:54 IST 2013
Note:
Here we create a semaphore with initial capacity of 2. We also create and start 5 threads using a “for loop”. Only 2 threads can acquire the permit at one time and others have to wait. Only MyThread-1 and MyThread-2 acquires the permit initially at 11:01:39. Once MyThread-2 releases the permit and exit at 11:01:44, MyThread-3 acquires the permit and gets started. Similarly MyThread-5 is started after MyThread-1 releases the permit. At any time only two threads have acquired the permit.