order service 6
You’re absolutely right! Let’s go one story at a time for better understanding. Here’s Story 6 only:
Story 6: Implement Thread Communication with BlockingQueue
// OrderProducer.java
import java.util.concurrent.BlockingQueue;
import java.util.Random;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
public class OrderProducer implements Runnable {
private final BlockingQueue<Order> orderQueue;
private final int numberOfOrders;
private final Random random = new Random();
private final String[] items = {"Laptop", "Mouse", "Keyboard", "Monitor", "iPhone", "AirPods"};
public OrderProducer(BlockingQueue<Order> orderQueue, int numberOfOrders) {
this.orderQueue = orderQueue;
this.numberOfOrders = numberOfOrders;
}
@Override
public void run() {
try {
for (int i = 0; i < numberOfOrders; i++) {
Order order = generateRandomOrder(i);
System.out.println("Producer adding order: " + order.getOrderId());
orderQueue.put(order); // Blocks if queue is full
Thread.sleep(random.nextInt(100)); // Simulate order arrival rate
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Producer interrupted");
}
}
private Order generateRandomOrder(int index) {
long orderId = 2000 + index;
long userId = 200 + random.nextInt(50);
boolean isPremium = random.nextBoolean();
// Random 1-3 items
int itemCount = 1 + random.nextInt(3);
List<String> orderItems = new ArrayList<>();
for (int i = 0; i < itemCount; i++) {
orderItems.add(items[random.nextInt(items.length)]);
}
double amount = 100 + random.nextDouble() * 1900;
return new Order(orderId, userId, orderItems, isPremium, amount);
}
}
// OrderConsumer.java
import java.util.concurrent.BlockingQueue;
public class OrderConsumer implements Runnable {
private final BlockingQueue<Order> orderQueue;
private final OrderProcessor processor;
private volatile boolean running = true;
public OrderConsumer(BlockingQueue<Order> orderQueue, OrderProcessor processor) {
this.orderQueue = orderQueue;
this.processor = processor;
}
@Override
public void run() {
try {
while (running) {
Order order = orderQueue.take(); // Blocks if queue is empty
System.out.println("Consumer " + Thread.currentThread().getName() +
" took order: " + order.getOrderId());
processor.processOrder(order);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Consumer interrupted");
}
}
public void stop() {
running = false;
}
}
// Main.java for Story 6
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws InterruptedException {
// Create blocking queue with capacity of 20
BlockingQueue<Order> orderQueue = new ArrayBlockingQueue<>(20);
// Create order processor (using the one from Story 5)
OrderProcessor processor = new OrderProcessor();
// Create thread pool for consumers
int consumerCount = 4;
ExecutorService consumerExecutor = Executors.newFixedThreadPool(consumerCount);
// Start consumers
OrderConsumer[] consumers = new OrderConsumer[consumerCount];
for (int i = 0; i < consumerCount; i++) {
consumers[i] = new OrderConsumer(orderQueue, processor);
consumerExecutor.submit(consumers[i]);
}
// Start producer
ExecutorService producerExecutor = Executors.newSingleThreadExecutor();
producerExecutor.submit(new OrderProducer(orderQueue, 50));
// Let it run for a while
Thread.sleep(10000);
// Shutdown
producerExecutor.shutdown();
for (OrderConsumer consumer : consumers) {
consumer.stop();
}
producerExecutor.awaitTermination(5, TimeUnit.SECONDS);
consumerExecutor.shutdown();
consumerExecutor.awaitTermination(5, TimeUnit.SECONDS);
System.out.println("System shutdown complete. Orders remaining in queue: " + orderQueue.size());
}
}
Key Concepts in Story 6:
- BlockingQueue – Thread-safe queue that blocks when full (for producers) or empty (for consumers)
- Producer-Consumer Pattern – Decouples order generation from processing
- ArrayBlockingQueue – Bounded queue with fixed capacity (20 in our case)
- put() and take() – Blocking operations that wait when necessary
What this achieves:
- Orders are produced at varying rates and queued safely
- Multiple consumers process orders concurrently
- No orders are lost due to thread coordination issues
- System can handle bursts of orders (up to queue capacity)
Would you like me to proceed with Story 7 next?