Thread-Safe Stock Inventory: Buy and Sell Without Overselling
OptiverSoftware Engineer · Technical ScreenLast updated
This question evaluates understanding of concurrent programming, synchronization primitives, atomicity, and correctness of shared mutable state by requiring implementation of a thread-safe inventory that prevents overselling and preserves updates.
Thread-Safe Stock Inventory: Buy and Sell Without Overselling
You are implementing the inventory-management core of a small brokerage service. The service tracks the number of shares of a single stock that are currently available, and it exposes two operations that will be called concurrently from many threads.
Implement a class StockInventory with the following interface:
StockInventory(initial)— construct the inventory withinitialshares available.buy(quantity)— acquirequantityadditional shares and add them to the available inventory. A buy always succeeds. Returns the number of shares available immediately after this purchase is applied.sell(quantity)— attempt to sellquantityshares out of the available inventory. The sale is all-or-nothing: if at leastquantityshares are available at the moment the sale is applied, deduct exactlyquantityshares and returntrue; otherwise leave the inventory unchanged and returnfalse. Partial fills are not allowed.
Correctness requirements
Your implementation must remain correct when an arbitrary number of threads call buy and sell simultaneously on the same StockInventory object:
- No overselling. The available share count must never become negative at any point in time. Two concurrent
sellcalls must never both succeed if the inventory can only cover one of them. - No lost updates. Every
buyand every successfulsellmust be reflected exactly once in the inventory. After all threads finish, the final count must equalinitial + (sum of all bought quantities) - (sum of all successfully sold quantities). - Atomic check-then-act. The availability check inside
selland the corresponding deduction must happen atomically with respect to all otherbuyandsellcalls — no other operation may interleave between the check and the update.
You may use the standard synchronization primitives provided by your language's library (mutexes/locks, atomic operations, condition variables, etc.). Keep the critical sections as small as correctness allows.
Example
Single-threaded illustration of the required semantics:
inv = StockInventory(100)
inv.sell(30) -> true (70 shares remain)
inv.sell(80) -> false (only 70 available; inventory unchanged at 70)
inv.buy(50) -> 120 (70 + 50)
inv.sell(120) -> true (0 shares remain)
inv.sell(1) -> false (inventory unchanged at 0)
Under concurrency, any interleaving of the calls is acceptable as long as every individual operation is atomic, the no-overselling invariant holds, and the final count is consistent with the set of operations that succeeded.
Constraints
0 <= initial <= 10^91 <= quantity <= 10^9for everybuyandsellcall- Up to
10^5total operations, issued from up to64concurrent threads - Each operation should complete in amortized $O(1)$ time outside of contention for the synchronization primitive
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.