Skip to content
On this page

Semaphore

In the previous discussions, we covered various lock implementations. The primary purpose of a lock is to protect a limited resource, ensuring that at any given time only one thread can access it (ReentrantLock), or only one thread can write to it (ReadWriteLock).

There is another scenario where a limited resource must ensure that no more than N threads can access it simultaneously. For example, limiting the number of database connections to 100 at any given time or allowing a maximum of 10 users to download simultaneously.

Implementing such a quantity restriction using an array of locks would be cumbersome. Instead, Semaphore is ideal for handling this situation. It allows setting a limit on the number of concurrent accesses. For instance, to permit a maximum of 3 threads to access simultaneously:

java
public class AccessLimitControl {
    // Allow up to 3 threads to acquire a permit at any given time:
    final Semaphore semaphore = new Semaphore(3);

    public String access() throws Exception {
        // If the number of permits is exceeded, other threads will wait here:
        semaphore.acquire();
        try {
            // Perform some task:
            return UUID.randomUUID().toString();
        } finally {
            semaphore.release();
        }
    }
}

With Semaphore, we first call acquire() to obtain a permit and then use a try ... finally block to ensure that the permit is released in the finally section.

Calling acquire() might cause the thread to wait until a permit becomes available. The tryAcquire() method allows specifying a maximum wait time:

java
if (semaphore.tryAcquire(3, TimeUnit.SECONDS)) {
    // Acquired a permit within 3 seconds:
    try {
        // Perform some task:
    } finally {
        semaphore.release();
    }
}

A Semaphore essentially acts as a counter that tracks the number of available permits, limiting the number of simultaneous accesses.

Summary

To limit access to a constrained resource, use a Semaphore to ensure that no more than N threads can access the resource at the same time.

Semaphore has loaded