Semaphore vs Mutex
In this article, we will learn about Semaphore vs Mutex!
1. Introduction
In concurrent programming, synchronization mechanisms play a crucial role in coordinating access to shared resources. Two commonly used synchronization primitives are semaphores and mutexes. Both serve the purpose of preventing race conditions and ensuring thread safety, but they differ in their usage and characteristics. In this article, we will explore the concepts of semaphores and mutexes, their differences, and provide code examples to illustrate their usage.
2. Semaphore
A semaphore is a synchronization primitive that maintains a counter and supports two fundamental operations: wait()
and signal()
. The counter represents the number of available resources. The wait()
operation decrements the counter and blocks if the counter reaches zero. The signal()
operation increments the counter, potentially releasing a waiting thread. Semaphores can have additional properties such as binary (0 or 1) or counting (arbitrary positive integer) semantics.
3. Mutex
A mutex, short for mutual exclusion, is a synchronization object used to protect a shared resource from concurrent access. Unlike a semaphore, which can have multiple resources, a mutex allows only one thread to acquire it at a time. When a thread acquires a mutex, it gains exclusive access to the protected resource. If another thread attempts to acquire the mutex while it is locked, it will be blocked until the mutex is released.
4. Differences between Semaphore and Mutex
4.1 Resource Management
- Semaphores: Semaphores are often used for managing a fixed number of resources that can be accessed concurrently. The counter associated with a semaphore represents the available resources.
- Mutexes: Mutexes are used to protect a single shared resource, ensuring that only one thread can access it at any given time.
4.2 Usage Patterns
- Semaphores: Semaphores are suitable for scenarios where multiple threads can access a shared resource simultaneously, up to a certain limit. They can also be used for signaling and coordination between threads.
- Mutexes: Mutexes are typically employed when exclusive access to a resource is required, and only one thread should be allowed to access it at a time.
4.3 Locking Mechanism
- Semaphores: The
wait()
operation on a semaphore will block if the counter reaches zero, effectively waiting for a resource to become available. Thesignal()
operation increments the counter, potentially releasing a waiting thread. - Mutexes: A thread that tries to acquire a locked mutex will be blocked until the mutex is released by the thread that currently owns it. Once released, one waiting thread will be able to acquire the mutex and access the protected resource.
5. Semaphore Example (Java)
import java.util.concurrent.Semaphore; public class SemaphoreExample { static Semaphore semaphore = new Semaphore(3); // Create a semaphore with 3 resources static class Worker implements Runnable { public void run() { try { semaphore.acquire(); System.out.println("Thread acquired semaphore"); // Perform operations with shared resource semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { for (int i = 0; i < 5; i++) { Thread t = new Thread(new Worker()); t.start(); } } }
6. Mutex Example (Java)
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class MutexExample { static Lock mutex = new ReentrantLock(); static class Worker implements Runnable { public void run() { mutex.lock(); System.out.println("Thread acquired mutex"); // Perform operations with shared resource mutex.unlock(); } } public static void main(String[] args) { Thread t1 = new Thread(new Worker()); Thread t2 = new Thread(new Worker()); t1.start(); t2.start(); } }
7. Conclusion
Semaphores and mutexes are essential synchronization mechanisms used in concurrent programming to prevent race conditions and ensure thread safety. While both serve similar purposes, they have distinct characteristics and are suited for different scenarios. Understanding the differences between semaphores and mutexes can help developers choose the appropriate synchronization mechanism for their specific use cases.
8. Download the Source Code
You can download the full source code of this example here: Semaphore vs Mutex