← Back to Questions
Java

What is Semaphore in Java?

Learn What is Semaphore in Java? with simple explanations, real-time examples, interview tips and practical use cases.

Semaphore in Java is a synchronization utility used to control access to a shared resource by multiple threads using a fixed number of permits.

In simple words:

Semaphore limits how many threads can access a resource simultaneously.


Why Semaphore is Important?

Modern enterprise applications need:

  • Controlled resource access
  • Connection pool management
  • Rate limiting
  • Thread coordination
  • Concurrent request control

Real-World Analogy

Imagine:

  • A parking lot with only 5 parking spaces
  • Only 5 cars can park at the same time
  • Other cars must wait

Parking Lot Flow


Parking Slots = 5

      |
      v

Cars Enter One by One

      |
      v

All Slots Full

      |
      v

New Cars Must Wait

      |
      v

Slot Released

      |
      v

Waiting Car Enters


Main Package

java.util.concurrent

How Semaphore Works?

Semaphore works using:

  • Permits
  • acquire()
  • release()

Internal Working Flow


Semaphore Created with 3 Permits

      |
      +-------> Thread 1 acquires permit

      |
      +-------> Thread 2 acquires permit

      |
      +-------> Thread 3 acquires permit

      |
      v

No Permits Left

      |
      v

Other Threads Wait

      |
      v

Permit Released

      |
      v

Waiting Thread Continues


Basic Semaphore Example

import java.util.concurrent.*;

class Worker extends Thread {

    private Semaphore semaphore;

    Worker(Semaphore semaphore) {

        this.semaphore = semaphore;

    }

    public void run() {

        try {

            semaphore.acquire();

            System.out.println(

                Thread.currentThread().getName()

                + " acquired permit"

            );

            Thread.sleep(2000);

            System.out.println(

                Thread.currentThread().getName()

                + " released permit"

            );

            semaphore.release();

        }
        catch(Exception e) {

            e.printStackTrace();

        }

    }

}

public class Main {

    public static void main(
        String[] args
    ) {

        Semaphore semaphore =

            new Semaphore(2);

        for(int i = 0; i < 5; i++) {

            new Worker(semaphore).start();

        }

    }

}

What Happens Internally?

  • Semaphore starts with 2 permits
  • Only 2 threads execute simultaneously
  • Remaining threads wait
  • release() returns permit back

Execution Flow


Thread Requests Permit

      |
      v

Permit Available?

      |
   YES | NO
      |
      v

Acquire Permit OR Wait

      |
      v

Thread Finishes Work

      |
      v

release() Returns Permit


Main Methods of Semaphore

Method Purpose
acquire() Acquire permit
release() Release permit
tryAcquire() Acquire permit without waiting
availablePermits() Returns available permits
drainPermits() Removes all permits

1. acquire()

Acquires a permit.


acquire() Flow


Thread Calls acquire()

      |
      v

Permit Available?

      |
   YES | NO
      |
      v

Proceed OR Wait


2. release()

Releases permit back to semaphore.


release() Example

semaphore.release();

3. tryAcquire()

Attempts to acquire permit immediately.


Example

if(semaphore.tryAcquire()) {

    try {

        // process

    }
    finally {

        semaphore.release();

    }

}

tryAcquire() Flow


Thread Requests Permit

      |
   YES | NO
      |
      v

Permit Acquired OR Immediate Failure


4. acquire(timeout)

Waits for permit with timeout.


Example

semaphore.tryAcquire(
    5,
    TimeUnit.SECONDS
);

Timeout Flow


Thread Waiting for Permit

      |
      v

Timeout Reached?

      |
   YES | NO
      |
      v

Continue OR Acquire Permit


Binary Semaphore

Semaphore with:

1 Permit

Works similar to a lock.


Binary Semaphore Flow


Only One Thread Allowed

      |
      v

Other Threads Wait

      |
      v

Permit Released

      |
      v

Next Thread Continues


Counting Semaphore

Semaphore with:

Multiple Permits

Counting Semaphore Flow


Multiple Threads Allowed

      |
      v

Permits Exhausted

      |
      v

Remaining Threads Wait


Fair Semaphore

Supports FIFO thread ordering.


Fair Semaphore Example

Semaphore semaphore =

    new Semaphore(3, true);

Fairness Flow


Thread 1 Requests Permit

Thread 2 Requests Permit

Thread 3 Requests Permit

      |
      v

Permits Granted in Arrival Order


Semaphore vs synchronized

Feature synchronized Semaphore
Thread Count One Thread Multiple Threads Possible
Permits No Yes
Fairness No Optional
Advanced Control Limited High

Semaphore vs ReentrantLock

Feature ReentrantLock Semaphore
Ownership Thread-Owned No Ownership
Permits Single Lock Multiple Permits
Main Use Mutual Exclusion Resource Limiting

Semaphore in Banking Systems

Banking applications use Semaphore for:

  • Database connection pools
  • ATM transaction limits
  • Concurrent payment control
  • Fraud detection throttling

Banking Flow


Database Connections = 10

      |
      v

Only 10 Transactions Allowed Concurrently

      |
      v

Extra Requests Wait


Semaphore in E-Commerce Systems

E-commerce platforms use Semaphore for:

  • Inventory locking
  • Concurrent checkout limits
  • API rate limiting
  • Connection management

E-Commerce Flow


Checkout Slots Limited

      |
      v

Customers Access Concurrently

      |
      v

Excess Requests Wait


Semaphore in Spring Boot

Spring Boot applications use Semaphore for:

  • API throttling
  • Rate limiting
  • Connection pool management
  • Async concurrency control

Spring Boot Example

Semaphore semaphore =

    new Semaphore(5);

public void processRequest()
    throws Exception {

    semaphore.acquire();

    try {

        // process request

    }
    finally {

        semaphore.release();

    }

}

Semaphore in Microservices

Microservices architectures use Semaphore for:

  • Distributed rate limiting
  • Service throttling
  • Connection control
  • Cloud resource management

Microservice Flow


API Gateway Receives Requests

      |
      v

Semaphore Limits Concurrent Requests

      |
      v

Excess Requests Queued


Advantages of Semaphore

  • Controls concurrent access
  • Supports multiple permits
  • Useful for resource pooling
  • Supports fairness
  • Improves scalability

Disadvantages

  • Incorrect release() causes issues
  • Complex debugging
  • Permit leaks possible
  • Improper usage may cause deadlocks

Common Interview Mistake

Many developers think Semaphore is only for mutual exclusion.

Actually:

  • Semaphore mainly controls resource limits.

Another Common Mistake

Many developers forget release().

Actually:

  • Missing release() causes permit leaks.

Best Practices

  • Always release permits in finally block
  • Use fair semaphores when required
  • Use tryAcquire() for timeout handling
  • Monitor permit usage in production
  • Avoid permit leaks

Realtime Enterprise Example

Cloud API Gateway


Maximum Concurrent API Requests = 100

      |
      v

Semaphore Controls Access

      |
      v

Extra Requests Wait or Rejected

      |
      v

System Remains Stable


Related Learning Topics


Professional Interview Answer

Semaphore is a synchronization utility in Java provided by the java.util.concurrent package that controls access to shared resources using a fixed number of permits. Threads acquire permits using acquire() before accessing a resource and release permits using release() after completing work. If no permits are available, additional threads wait until permits are released. Semaphores can function as binary semaphores with a single permit or counting semaphores with multiple permits. Enterprise applications, Spring Boot systems, distributed microservices, banking platforms, cloud-native architectures, API gateways, e-commerce systems, and high-concurrency applications heavily use semaphores for connection pooling, rate limiting, thread coordination, resource throttling, and concurrent request management. Semaphore provides more flexible concurrency control than synchronized because it supports multiple concurrent accesses, fairness policies, timeout handling, and scalable resource management.


Frequently Asked Questions

What is Semaphore in Java?

Semaphore is a synchronization utility that controls concurrent access to shared resources using permits.

Which package contains Semaphore?

java.util.concurrent

What is the purpose of acquire()?

It acquires a permit before accessing a shared resource.

What is binary semaphore?

A semaphore with one permit, similar to a lock.

Where is Semaphore used?

Connection pools, rate limiting, Spring Boot systems, banking platforms, API gateways, and distributed microservices.

Why this Java question is important?

This interview question helps candidates understand real-time backend development concepts, practical problem solving, coding fundamentals, system design basics and production-ready application behavior.

Practice this question carefully for Java backend roles, Spring Boot developer interviews, microservices interviews, company interviews and full-stack developer preparation.

About the Author

Naresh Kumar is a Senior Java Backend Engineer with experience building enterprise applications using Java, Spring Boot, Microservices, Docker, Kubernetes and Cloud technologies.