Multithreading
Semaphore
Manage resource pools using counting semaphores and throttling policies.
Interview: Commonly tested on counting permits, binary semaphores vs locks, and throttling concurrent resources.
A Semaphore maintains a set of permits. Threads block when calling acquire() if no permits are available. This makes semaphores perfect for throttling and managing resource pools.
Core Idea
A Semaphore regulates access using permits. acquire() decrements permits, release() increments them.
Why It Matters
It throttles incoming loads to protect databases or downstream APIs from crashing due to sudden spikes.
Interview Lens
Focuses on comparing binary semaphores (size 1) to ReentrantLock and verifying lock ownership rules.
Binary Semaphore vs. Lock
A semaphore with 1 permit is called a binary semaphore. While it behaves similarly to a Lock (providing mutual exclusion), there is a key difference:
- Lock Ownership: A standard Lock has ownership: the thread that acquires it must release it.
- No Ownership: A Semaphore does not track which thread acquired a permit. Any thread can call
release()to add a permit, which is useful for coordination patterns but requires care to avoid logic errors.
Code Walkthrough
This class uses a Semaphore to limit the number of active network calls to a database service.
import java.util.concurrent.Semaphore;public class DatabaseThrottler { private final Semaphore semaphore = new Semaphore(3); // Allow max 3 parallel calls
public void queryDatabase() { try { semaphore.acquire(); // Blocks if 3 threads are already executing try { System.out.println(Thread.currentThread().getName() + " executing DB query"); Thread.sleep(1000); // Simulate network query } finally { semaphore.release(); // Always release permit! } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }
Interview-Relevant Information
Q: Does release() increment permits past the initial size?
Answer: Yes. If you instantiate a semaphore with 3 permits, and threads call release() without calling acquire() first, the number of available permits will grow past 3. To maintain a strict limit, you must ensure that every release corresponds to a successful acquire.
Quick Checklist
How does a semaphore differ from a lock? What is a binary semaphore? If yes, you understand semaphores.
Use Cases
Limiting the number of concurrent connections to external APIs to avoid rate limits.
Implementing database connection pools.
Common Mistakes
Forgetting to call release() inside a finally block, which permanently leaks the permit and deadlocks subsequent callers.
Spawning duplicate release calls, increasing the maximum concurrent permit count.