Design Bounded Blocking Queue - Problem

Design and implement a thread-safe bounded blocking queue that efficiently handles concurrent access from multiple producer and consumer threads.

Your queue should support the following operations:

  • BoundedBlockingQueue(int capacity) - Initialize the queue with a maximum capacity
  • void enqueue(int element) - Add an element to the rear of the queue. If the queue is full, the calling thread should block until space becomes available
  • int dequeue() - Remove and return the element from the front of the queue. If the queue is empty, the calling thread should block until an element becomes available
  • int size() - Return the current number of elements in the queue

Key Requirements:

  • The implementation must be thread-safe and handle concurrent access properly
  • Producer threads will only call enqueue()
  • Consumer threads will only call dequeue()
  • Blocking behavior is essential - threads must wait when the queue is full/empty
  • Do not use built-in blocking queue implementations

This is a fundamental concurrency problem that tests your understanding of synchronization primitives like locks, condition variables, and thread coordination.

Input & Output

example_1.py โ€” Basic Operations
$ Input: capacity = 3 operations: [enqueue(1), enqueue(2), size(), dequeue(), size()]
โ€บ Output: [null, null, 2, 1, 1]
๐Ÿ’ก Note: Create queue with capacity 3, add elements 1 and 2 (size becomes 2), remove element 1 from front (size becomes 1). Operations execute without blocking since queue is neither full nor empty.
example_2.py โ€” Blocking Behavior
$ Input: capacity = 2 Thread 1: enqueue(1), enqueue(2), enqueue(3) [blocks on third] Thread 2: dequeue() [returns 1, unblocks Thread 1]
โ€บ Output: Thread 1 completes enqueue(3), Thread 2 gets 1
๐Ÿ’ก Note: Thread 1 fills the queue and blocks on the third enqueue. When Thread 2 dequeues an element, it creates space and Thread 1 can complete its operation.
example_3.py โ€” Empty Queue Blocking
$ Input: capacity = 2 Thread 1: dequeue() [blocks on empty queue] Thread 2: enqueue(5) [unblocks Thread 1]
โ€บ Output: Thread 1 gets 5 from dequeue()
๐Ÿ’ก Note: Thread 1 tries to dequeue from an empty queue and blocks. When Thread 2 adds element 5, Thread 1 is unblocked and receives that element.

Visualization

Tap to expand
Producer-Consumer with Condition VariablesProducersBounded Queue[1][2][ ]ConsumersnotFullConditionnotEmptyConditionwait()wait()signal()signal()Efficient Coordinationโœ“ No busy waiting - threads sleep until conditions are metโœ“ Immediate notification when state changesโœ“ Scalable to many concurrent producers and consumers
Understanding the Visualization
1
Setup
Initialize queue with mutex lock and two condition variables: notFull and notEmpty
2
Producer Waits
When queue is full, producer thread waits on notFull condition variable
3
Consumer Signals
After dequeue, consumer signals notFull to wake up waiting producers
4
Consumer Waits
When queue is empty, consumer thread waits on notEmpty condition variable
5
Producer Signals
After enqueue, producer signals notEmpty to wake up waiting consumers
Key Takeaway
๐ŸŽฏ Key Insight: Condition variables provide the perfect mechanism for thread coordination - they eliminate busy waiting while ensuring threads wake up immediately when their conditions can be satisfied, making the solution both efficient and scalable.

Time & Space Complexity

Time Complexity
โฑ๏ธ
O(1)

Each operation is O(1) with efficient blocking - no wasted cycles

n
2n
โœ“ Linear Growth
Space Complexity
O(n)

Space for queue elements plus small overhead for synchronization primitives

n
2n
โšก Linearithmic Space

Constraints

  • 1 โ‰ค capacity โ‰ค 103
  • 0 โ‰ค element โ‰ค 106
  • At most 104 operations will be performed
  • Must handle concurrent access from multiple threads
  • Implementation must be thread-safe without using built-in blocking queues
Asked in
Google 45 Amazon 38 Microsoft 32 Meta 28
78.0K Views
High Frequency
~35 min Avg. Time
2.9K Likes
Ln 1, Col 1
Smart Actions
๐Ÿ’ก Explanation
AI Ready
๐Ÿ’ก Suggestion Tab to accept Esc to dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen