Imagine you and your friends are waiting to use a washing machine.
- If there is only one washing machine, only one person can use it at a time.
- If there are five washing machines, then five people can use them simultaneously.
This is exactly what a Semaphore does in programming.
A Semaphore is a synchronization mechanism that limits the number of threads that can access a shared resource simultaneously.
Key Concepts
- A Semaphore uses permits.
-
acquire()takes a permit. If no permits are available, the thread waits. -
release()returns a permit back to the semaphore. -
Semaphore(5)allows up to 5 concurrent threads to access a shared resource.
Producer-Consumer
The Producer-Consumer Problem is one of the most common use cases of semaphores.
- A Producer creates items and places them into a shared buffer.
- A Consumer removes items from the shared buffer.
Semaphores coordinate access so that:
- The producer does not overfill the buffer.
- The consumer does not consume from an empty buffer.
This ensures proper synchronization between producer and consumer threads.
Mutex vs Semaphore
Mutex
A Mutex allows only one thread to access the critical section at a time.
Characteristics
- Only ONE thread can enter the critical section.
- Used for mutual exclusion.
- Prevents race conditions by ensuring exclusive access to shared resources.
Semaphore
A Semaphore allows multiple threads to access a shared resource based on the number of permits available.
Characteristics
- Allows multiple threads simultaneously.
- The number of concurrent threads depends on the number of permits.
- Example:
Semaphore(5)allows up to 5 threads to access the resource at the same time.
Java Example
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) throws InterruptedException {
Semaphore semaphore = new Semaphore(5);
semaphore.acquire();
// Critical section
System.out.println("Thread is accessing the shared resource.");
semaphore.release();
}
}
Conclusion
- Use a Mutex when only one thread should access a shared resource at a time.
- Use a Semaphore when a limited number of threads can access the resource simultaneously.
Common real-world use cases include:
- Database connection pools
- Printer management
- Thread pools
- API rate limiting
- Parking lot simulations
- Producer-Consumer systems
Semaphores help efficiently manage concurrent access to shared resources while preventing conflicts and improving application performance.
Top comments (0)