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
- What is ReentrantLock in Java
- What is CountDownLatch in Java
- What is CyclicBarrier in Java
- What is Thread Pool in Java
- What is Multithreading in Java
- What is Producer-Consumer Problem in Java
- What are Microservices
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.