Java Counting Semaphore maintains a specified number of passes or permissions, and the Current Thread must obtain a permit to access a shared resource. If a permit is already exhausted by threads other than that, it may wait until the permit becomes available as a result of the release of permits from various threads. This concurrency utility can be very useful for implementing a pattern of producer-consumer design or implementing limited pools of assets such as Thread Pool, DB Connection Pool, etc. The class java.util.Semaphore is a Counting Semaphore that is initialized with a number of permissions.Â
Semaphore provides two main methods for obtaining permits and releasing permits
- acquire(): This method acquires a permit if one is available, and returns immediately, reducing the number of available permits by one. If the current thread is interrupted while waiting for a permit then InterruptedException is thrown.
- release(): This method acquires the given number of permits, if they are available, and returns immediately, reducing the number of available permits by the given amount. If the current thread is interrupted while waiting for a permit then InterruptedException is thrown.
Implementation:
A binary semaphore is known as a Counting semaphore with one permit because it only has two state permits available or unavailable permits. To execute mutual exclusion or critical section where only one thread is allowed to execute, a binary semaphore can be used. A thread waits on acquire() until Thread allows release within the critical section by calling release() on the semaphore. Below is java semaphore counting where binary semaphore is used to provide shared exclusive access to essential code parts
Example:
Java
// Java Program to illustrate use Counting Semaphore // in Concurrent Java Application Â
import java.util.concurrent.Semaphore; Â
public class SemaphoreTest { Â
    // Initialize the semaphore with the number     // of permits required Â
    // Here only 1 permit is allowed     Semaphore binary = new Semaphore( 1 ); Â
    // Main driver method     public static void main(String args[])     { Â
        final SemaphoreTest test = new SemaphoreTest(); Â
        // Thread 1         new Thread() {                        // Method that should be executed for thread1             @Override public void run()             {                 test.mutualExclusion();             }         }.start(); Â
        // Thread 2         new Thread() {                        // Method that should be executed for thread2             @Override public void run()             {                 test.mutualExclusion();             }         }.start();     } Â
    // Method     private void mutualExclusion()     { Â
        // Try block to check for exceptions         try {             // acquire() acts as an input to semaphore             // to check for available permits             binary.acquire(); Â
            // Mutual exclusive region Â
            System.out.println(                 Thread.currentThread().getName()                 + " inside mutual exclusive " ); Â
            // sleep() method is used to hold thread for             // sometime Parameter is nanoseconds to be             // holded             Thread.sleep( 1000 );         } Â
        // Catch block to handle the exception Â
        // Handling exception if thread is interrupted         // either before or during the activity         catch (InterruptedException e) { Â
            // Print and display the line number where             // exception occurred             e.printStackTrace();         } Â
        finally { Â
            // release() method acts as output to semaphore             // When thread operation is completed             // release() method increase the permits             // in the semaphore             binary.release(); Â
            // Printing the thread name             // using the getName() method             System.out.println(                 Thread.currentThread().getName()                 + " outside of mutual exclusive " );         }     } } |
Thread-0 inside mutual exclusive Thread-1 inside mutual exclusive Thread-0 outside of mutual exclusive Thread-1 outside of mutual exclusive