How does Semaphore behave in multithreaded code?

A Semaphore is a synchronization primitive that is used to control access to a common resource in a concurrent system such as a multitasking operating system. It maintains a set of permits, and each acquire operation decreases the number of permits, while each release operation increases it. This allows multiple threads to manage access to a resource and coordinate their execution, preventing race conditions and ensuring that a specified number of threads can access a resource simultaneously.

In multithreaded code, a Semaphore can be beneficial for managing concurrent access to shared resources, like databases, file systems, or network connections. For example, if you have a limited number of database connections available, you can use a Semaphore to limit the number of threads that can use those connections at the same time. This way, when a thread acquires a permit, it indicates that it is using one of the available resources, and when it is done, it releases the permit, allowing another thread to use the resource.

Here is an example of using a Semaphore in Java:

import java.util.concurrent.Semaphore; public class SemaphoreExample { private static final int MAX_PERMITS = 3; private static final Semaphore semaphore = new Semaphore(MAX_PERMITS); public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(new Worker(i)).start(); } } static class Worker implements Runnable { private final int id; Worker(int id) { this.id = id; } @Override public void run() { try { System.out.println("Worker " + id + " is waiting to acquire a permit."); semaphore.acquire(); System.out.println("Worker " + id + " has acquired a permit."); // Simulate work Thread.sleep(2000); System.out.println("Worker " + id + " is releasing the permit."); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } } } }

Semaphore Multithreading Java Synchronization Resource Management