0
0
JavaConceptBeginner · 3 min read

Semaphore in Java: What It Is and How It Works

In Java, a Semaphore is a synchronization tool that controls access to a shared resource by multiple threads using permits. It allows a fixed number of threads to access a resource simultaneously, blocking others until permits are released.
⚙️

How It Works

Imagine a parking lot with a limited number of parking spots. Each spot represents a permit. When a car (thread) arrives, it can park only if there is a free spot (permit). If all spots are taken, the car must wait until someone leaves and frees a spot.

In Java, a Semaphore works the same way. It has a set number of permits. Threads must acquire a permit before proceeding. If no permits are available, the thread waits. When a thread finishes, it releases its permit, allowing others to proceed.

This mechanism helps manage concurrent access to resources like database connections or files, preventing conflicts and ensuring smooth operation.

💻

Example

This example shows a Semaphore with 2 permits allowing only two threads to run a critical section at the same time.

java
import java.util.concurrent.Semaphore;

public class SemaphoreExample {
    private static final Semaphore semaphore = new Semaphore(2);

    static class Worker extends Thread {
        private final int id;

        Worker(int id) {
            this.id = id;
        }

        public void run() {
            try {
                System.out.println("Thread " + id + " is waiting for a permit.");
                semaphore.acquire(); // acquire a permit
                System.out.println("Thread " + id + " acquired a permit.");

                // Simulate work
                Thread.sleep(2000);

                System.out.println("Thread " + id + " is releasing a permit.");
                semaphore.release(); // release the permit
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public static void main(String[] args) {
        for (int i = 1; i <= 5; i++) {
            new Worker(i).start();
        }
    }
}
Output
Thread 1 is waiting for a permit. Thread 1 acquired a permit. Thread 2 is waiting for a permit. Thread 2 acquired a permit. Thread 3 is waiting for a permit. Thread 4 is waiting for a permit. Thread 5 is waiting for a permit. Thread 1 is releasing a permit. Thread 3 acquired a permit. Thread 2 is releasing a permit. Thread 4 acquired a permit. Thread 3 is releasing a permit. Thread 5 acquired a permit. Thread 4 is releasing a permit. Thread 5 is releasing a permit.
🎯

When to Use

Use a Semaphore when you need to limit how many threads can access a resource at the same time. For example:

  • Controlling access to a pool of database connections.
  • Limiting the number of users downloading a file simultaneously.
  • Managing access to hardware devices like printers.

This helps avoid overload, resource conflicts, or crashes by ensuring only a safe number of threads work concurrently.

Key Points

  • Semaphore controls access using permits.
  • Threads must acquire() before proceeding and release() after finishing.
  • It can allow multiple threads simultaneously, unlike a simple lock.
  • Useful for managing limited resources safely.

Key Takeaways

Semaphore limits how many threads can access a resource at once using permits.
Threads call acquire() to get a permit and release() to free it.
It helps prevent resource conflicts and overload in concurrent programs.
Use Semaphore when you have a fixed number of resources shared by many threads.