Friday, September 15, 2023

How to use Counting Semaphore in Concurrent Java Application? Example Tutorial

Counting Semaphore in Java is a synchronizer that allows imposing a bound on the resource is added in Java 5 along with other popular concurrent utilities like CountDownLatch, CyclicBarrier, and Exchanger, etc. Counting Semaphore in Java maintains a specified number of pass or permits, In order to access a shared resource, Current Thread must acquire a permit. If a permit is already exhausted by other threads than it can wait until a permit is available due to the release of permits from different threads. This concurrency utility can be very useful to implement a producer-consumer design pattern or implement bounded pool or resources like Thread Pool, DB Connection pool, etc.

The java.util.Semaphore class represents a Counting semaphore which is initialized with a number of permits. Semaphore provides two main methods acquire() and release() for getting permits and releasing permits. acquire() method blocks until permit is available. 

Semaphore provides both blocking methods as well as unblocking method to acquire permits. This Java concurrency tutorial focuses on a very simple example of Binary Semaphore and demonstrates how mutual exclusion can be achieved using Semaphore in Java.


Counting Semaphore Example in Java (Binary Semaphore)

Java 5 Semaphore Example codea Counting semaphore with one permit is known as binary semaphore because it has only two state permit available or permit unavailable. Binary semaphore can be used to implement mutual exclusion or critical section where only one thread is allowed to execute. 

Thread will wait on acquire() until Thread inside critical section release permit by calling release() on semaphore.



here is a simple example of counting semaphore in Java where we are using binary semaphore to provide mutually exclusive access on a critical section of code in java:

import java.util.concurrent.Semaphore;

public class SemaphoreTest {

    Semaphore binary = new Semaphore(1);
 
    public static void main(String args[]) {
        final SemaphoreTest test = new SemaphoreTest();
        new Thread(){
            @Override
            public void run(){
              test.mutualExclusion();
            }
        }.start();
     
        new Thread(){
            @Override
            public void run(){
              test.mutualExclusion();
            }
        }.start();
     
    }
 
    private void mutualExclusion() {
        try {
            binary.acquire();

            //mutual exclusive region
            System.out.println(Thread.currentThread().getName() + " inside mutual exclusive region");
            Thread.sleep(1000);

        } catch (InterruptedException i.e.) {
            ie.printStackTrace();
        } finally {
            binary.release();
            System.out.println(Thread.currentThread().getName() + " outside of mutual exclusive region");
        }
    }
 
}

Output:
Thread-0 inside mutual exclusive region
Thread-0 outside of mutual exclusive region
Thread-1 inside mutual exclusive region
Thread-1 outside of mutual exclusive region


Some Scenario where Semaphore can be used:

1) To implement a better Database connection pool which will block if no more connection is available instead of failing and handover Connection as soon as it's available.

2) To put a bound on collection classes. by using semaphore you can implement bounded collection whose bound is specified by counting semaphore. You can further see these Java Multithreading courses to learn more about Semaphore and other advanced Concurrency utilities in Java. 



Important points of Counting Semaphore in Java

1. Semaphore class supports the various overloaded versions of tryAquire() method which acquires permit from semaphore only if its available during time of call.

2. Another worth noting method from Semaphore is acquireUninterruptibly() which is a blocking call and wait until a permit is available.

That's all on Counting semaphore example in JavaSemaphore is real nice concurrent utility which can greatly simply design and implement of the bounded resource pool. Java 5 has added several useful concurrent utilities and deserves better attention than a casual look


Other Java concurrency tutorial you may like

 And lastly one question for you? What is difference between Semaphore and CountDownLatch in Java? Can you use Semaphore in place of CountDownLatch?

5 comments :

Anonymous said...

Hy there,

you didn't mention what the expected outcome is. If the expected outcome is to always get an "inside" and then an "outside", it would be wrong.

In the example it actually should never happen. But if you had more threads started or you do not wait, you will get "inside" "inside"...

maxx

Anonymous said...

to get the mentioned output make mutualExclusion method synchronized.

Anonymous said...

include sysout before release.

Anonymous said...

Can someone help me to generate the output(using semaphore) 1Aa2Bb3Cc...so on, if i have 3 threads(one printing numbers,one printing capital letters,one printing small letters).

Anonymous said...

[include sysout before release. ]
That solved the issue!

Post a Comment