order service 7
Story 7: Add Priority Management for Premium Users
// PrioritizedOrder.java
public class PrioritizedOrder implements Comparable<PrioritizedOrder> {
private final Order order;
private final long timestamp;
public PrioritizedOrder(Order order) {
this.order = order;
this.timestamp = System.nanoTime();
}
public Order getOrder() {
return order;
}
@Override
public int compareTo(PrioritizedOrder other) {
// Premium orders have higher priority (come first)
if (this.order.isPremiumUser() && !other.order.isPremiumUser()) {
return -1;
} else if (!this.order.isPremiumUser() && other.order.isPremiumUser()) {
return 1;
}
// If both are same type, use FIFO based on timestamp
return Long.compare(this.timestamp, other.timestamp);
}
}
// PriorityOrderProducer.java
import java.util.concurrent.PriorityBlockingQueue;
import java.util.Random;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
public class PriorityOrderProducer implements Runnable {
private final PriorityBlockingQueue<PrioritizedOrder> orderQueue;
private final int numberOfOrders;
private final Random random = new Random();
private final String[] items = {"Laptop", "Mouse", "Keyboard", "Monitor", "iPhone", "AirPods"};
public PriorityOrderProducer(PriorityBlockingQueue<PrioritizedOrder> 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);
PrioritizedOrder prioritizedOrder = new PrioritizedOrder(order);
System.out.println("Producer adding " +
(order.isPremiumUser() ? "PREMIUM" : "REGULAR") +
" order: " + order.getOrderId());
orderQueue.put(prioritizedOrder);
Thread.sleep(random.nextInt(50));
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
private Order generateRandomOrder(int index) {
long orderId = 3000 + index;
long userId = 300 + random.nextInt(50);
// 30% chance of premium user
boolean isPremium = random.nextDouble() < 0.3;
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);
}
}
// PriorityOrderConsumer.java
import java.util.concurrent.PriorityBlockingQueue;
public class PriorityOrderConsumer implements Runnable {
private final PriorityBlockingQueue<PrioritizedOrder> orderQueue;
private final OrderProcessor processor;
private volatile boolean running = true;
public PriorityOrderConsumer(PriorityBlockingQueue<PrioritizedOrder> orderQueue, OrderProcessor processor) {
this.orderQueue = orderQueue;
this.processor = processor;
}
@Override
public void run() {
// Set thread priority based on consumer type
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
try {
while (running) {
PrioritizedOrder prioritizedOrder = orderQueue.take();
Order order = prioritizedOrder.getOrder();
// Adjust thread priority dynamically based on order type
if (order.isPremiumUser()) {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
} else {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
}
System.out.println("Consumer " + Thread.currentThread().getName() +
" processing " + (order.isPremiumUser() ? "PREMIUM" : "REGULAR") +
" order: " + order.getOrderId());
processor.processOrder(order);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public void stop() {
running = false;
}
}
// PriorityMain.java - Main class for Story 7
import java.util.concurrent.*;
public class PriorityMain {
public static void main(String[] args) throws InterruptedException {
// Create priority blocking queue
PriorityBlockingQueue<PrioritizedOrder> orderQueue = new PriorityBlockingQueue<>();
OrderProcessor processor = new OrderProcessor();
// Create consumers
int consumerCount = 3;
ExecutorService consumerExecutor = Executors.newFixedThreadPool(consumerCount);
PriorityOrderConsumer[] consumers = new PriorityOrderConsumer[consumerCount];
for (int i = 0; i < consumerCount; i++) {
consumers[i] = new PriorityOrderConsumer(orderQueue, processor);
consumerExecutor.submit(consumers[i]);
}
// Create multiple producers to simulate rush
ExecutorService producerExecutor = Executors.newFixedThreadPool(2);
producerExecutor.submit(new PriorityOrderProducer(orderQueue, 30));
producerExecutor.submit(new PriorityOrderProducer(orderQueue, 30));
// Let it run
Thread.sleep(15000);
// Shutdown
producerExecutor.shutdown();
for (PriorityOrderConsumer consumer : consumers) {
consumer.stop();
}
producerExecutor.awaitTermination(5, TimeUnit.SECONDS);
consumerExecutor.shutdown();
consumerExecutor.awaitTermination(5, TimeUnit.SECONDS);
System.out.println("Priority system shutdown. Remaining orders: " + orderQueue.size());
}
}
Key Concepts in Story 7:
- PriorityBlockingQueue – Automatically sorts elements based on their Comparable implementation
- Comparable Interface – PrioritizedOrder implements compareTo() to define priority rules
- Thread Priority – Using Thread.setPriority() to give OS hints about thread scheduling
- Wrapper Pattern – PrioritizedOrder wraps Order with priority information
What this achieves:
- Premium orders are processed before regular orders
- Within same priority level, FIFO order is maintained (using timestamp)
- Thread priority adjusts dynamically based on order type
- System simulates real e-commerce scenario where premium customers get faster service
Sample Output:
Producer adding REGULAR order: 3000
Producer adding PREMIUM order: 3001
Producer adding REGULAR order: 3002
Consumer pool-1-thread-1 processing PREMIUM order: 3001
Consumer pool-1-thread-2 processing REGULAR order: 3000
Consumer pool-1-thread-3 processing REGULAR order: 3002
Would you like me to proceed with Story 8 next?