Skip to content

Commit defff5c

Browse files
committed
feat: add UnboundedQueueDemo illustrating producer-consumer model with LinkedBlockingQueue
Implemented UnboundedQueueDemo.java to demonstrate unbounded blocking queue behavior using LinkedBlockingQueue. Showcases asynchronous coordination between producer and consumer threads where put() and take() handle synchronization automatically without capacity limits. Signed-off-by: https://github.com/Someshdiwan <[email protected]>
1 parent 8db03ac commit defff5c

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
An unbounded queue has no fixed capacity limit — it can grow dynamically
2+
until available system memory is exhausted.
3+
4+
Producers adding elements never block, as the queue always accepts new items.
5+
6+
In Java:
7+
- `LinkedBlockingQueue` → optionally bounded, but unbounded by default (capacity = Integer.MAX_VALUE).
8+
- `PriorityBlockingQueue` → always unbounded, ordered by priority or natural order.
9+
- `DelayQueue` → always unbounded, elements become available only after their delay expires.
10+
11+
This design is useful when the number of elements is unpredictable and memory
12+
resources are sufficient.
13+
14+
Unbounded Queue (e.g., `LinkedBlockingQueue`, `DelayQueue`)
15+
16+
┌────────────────────────────────────────────┐
17+
│ Unbounded BlockingQueue │
18+
│────────────────────────────────────────────│
19+
Producer →│ [Task1] → [Task2] → [Task3] → [Task4] → … │→ Consumer
20+
│────────────────────────────────────────────│
21+
│ • No fixed capacity limit │
22+
│ • Grows dynamically (until memory limit) │
23+
│ • put() never blocks │
24+
│ • take() blocks if queue is empty │
25+
└────────────────────────────────────────────┘
26+
27+
28+
Producer threads:
29+
┌───────────┐ ┌───────────┐ ┌───────────┐
30+
│ Producer1 │ →→→ │ Producer2 │ →→→ │ Producer3 │
31+
└───────────┘ └───────────┘ └───────────┘
32+
│ │ │
33+
▼ ▼ ▼
34+
┌──────────────────────────────────────────────────┐
35+
│ Queue: [Task1][Task2][Task3][Task4][Task5]…∞ │
36+
└──────────────────────────────────────────────────┘
37+
38+
39+
🚀 Keeps accepting new tasks (until memory full)
40+
41+
Consumer thread:
42+
┌───────────┐
43+
│ Consumer1 │ → takes → processes → repeats
44+
└───────────┘
45+
46+
47+
Summary of Behavior
48+
49+
| Queue Type | Capacity Type | put() when Full | take() when Empty| Example Use Case |
50+
|--------------------------|---------------|------------------|------------------|-------------------------------------|
51+
| `LinkedBlockingQueue` | Unbounded | Never blocks | Blocks | Generic producer-consumer model |
52+
| `PriorityBlockingQueue` | Unbounded | Never blocks | Blocks | Priority-based task scheduling |
53+
| `DelayQueue` | Unbounded | Never blocks | Blocks (until delay expires) | Delayed job execution |
54+
55+
In short:
56+
An unbounded queue favors flexibility and throughput by eliminating
57+
capacity restrictions.
58+
59+
It is ideal for applications where queue size is expected to remain reasonable,
60+
but it can be risky if producers outpace consumers — potentially causing
61+
OutOfMemoryError due to uncontrolled growth.
62+
63+
64+
┌────────────────────────────────────────────┐
65+
│ Unbounded BlockingQueue │
66+
│────────────────────────────────────────────│
67+
Producer →│ [Task1] → [Task2] → [Task3] → [Task4] → … │→ Consumer
68+
│────────────────────────────────────────────│
69+
│ • No fixed capacity limit │
70+
│ • Grows dynamically (until memory limit) │
71+
│ • put() never blocks │
72+
│ • take() blocks if queue is empty │
73+
└────────────────────────────────────────────┘
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import java.util.concurrent.*;
2+
3+
public class UnboundedQueueDemo {
4+
public static void main(String[] args) throws InterruptedException {
5+
BlockingQueue<String> queue = new LinkedBlockingQueue<>(); // unbounded by default
6+
7+
// Producer Thread
8+
new Thread(() -> {
9+
try {
10+
for (int i = 1; i <= 5; i++) {
11+
queue.put("Task-" + i);
12+
System.out.println("Produced: Task-" + i);
13+
Thread.sleep(500);
14+
}
15+
} catch (InterruptedException e) {
16+
Thread.currentThread().interrupt();
17+
}
18+
}).start();
19+
20+
// Consumer Thread
21+
new Thread(() -> {
22+
try {
23+
while (true) {
24+
String task = queue.take();
25+
System.out.println("Consumed: " + task);
26+
Thread.sleep(1000);
27+
}
28+
} catch (InterruptedException e) {
29+
Thread.currentThread().interrupt();
30+
}
31+
}).start();
32+
}
33+
}

0 commit comments

Comments
 (0)