Katkat

Implement a multithreaded task executor with semaphores

SoFiSoftware Engineer · Technical Screen

Last updated

This question evaluates understanding of concurrent programming, thread-safety, semaphore-style resource management, exception-safe permit release, and extensible API design, and it falls under the Coding & Algorithms category testing concurrency/multithreading, synchronization primitives, and resource management.

Design and implement a thread-safe TaskExecutor that limits concurrent work using a semaphore-like mechanism.

You are given an interface similar to:

  • initialize(int maxThreads): sets up the executor with a maximum number of “worker permits”.
  • acquire(int permits): blocks until the requested number of permits is available, then reserves them.
  • execute(Task task, int input): runs a task while respecting the permit limit.

A Task is an interface and multiple subclasses implement different behaviors, but all must use the same interface. Each task declares:

  • how many threads/permits it requires (e.g., requiredPermits()), and
  • whether execute(...) should block until the task finishes (blocking) or return immediately while the task continues in the background (fire-and-forget).

Example tasks:

  • MultiplyTask(factor, xPermits): multiplies input by factor, requires xPermits, and is fire-and-forget (i.e., execute should not wait for completion).
  • DivideTask(divisor, yPermits): divides input by divisor, requires yPermits, and is blocking (i.e., execute returns only after completion and returns the computed result).

Requirements:

  1. Total permits in use across all running tasks must never exceed maxThreads.
  2. Permits must be released reliably even if a task throws.
  3. The design should be extensible/maintainable: adding a new Task type should not require changing TaskExecutor logic beyond using the common Task interface.
  4. Avoid busy-waiting; use proper concurrency primitives.

Specify the key classes/interfaces and implement the core logic of initialize, acquire, and execute (language: Java or pseudocode acceptable).