AlgoMaster Logo
AlgoMasterDesign a Concurrency Limiter With a Semaphoremedium

Design a Concurrency Limiter With a Semaphore

medium

Design a reusable concurrency limiter that allows at most a fixed number of callbacks to execute simultaneously.

Implement the ConcurrencyLimiter class:

  • ConcurrencyLimiter(maxConcurrent) creates a limiter containing maxConcurrent permits.
  • run(task) waits for one permit, executes task, and releases the permit when the task finishes.

At most maxConcurrent callbacks passed to the same limiter may be executing at once. A caller for which no permit is available must block until another callback releases one.

Permits must be reusable across any number of calls. The permit must also be released if the callback throws an unchecked exception or panics; the original failure should continue to the caller after cleanup.

Different ConcurrencyLimiter instances must have independent permit pools.

The judge creates all caller threads and supplies the callbacks. Standard concurrency, callback, and thread APIs are preloaded, so you do not need import, include, or using statements.

Example 1:

Input:

Output:

Example 2:

Input:

Output:

Constraints

  • 1 <= maxConcurrent <= 32
  • At most 50000 calls to run are made per limiter.
  • A task may complete normally or fail with an unchecked exception or panic.
  • Tasks do not call run recursively on the same limiter.
  • Judge threads are not interrupted while waiting for a permit.
Loading...

Input

limiter = ConcurrencyLimiter(2)
four threads call limiter.run(slowTask)

Output

all four tasks complete
at most two slowTask callbacks overlap

Run is a quick check against the first couple of scenarios, which is roughly what these examples describe. Submit puts your class under the full set, which stays hidden.