Coordinating Different Collections - Java Thread

Java examples for Thread:synchronized

Description

Coordinating Different Collections

Demo Code

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;

public class Main {
  Set<Thread> orderingThreads = new HashSet<>();

  public static void main(String[] args) throws InterruptedException {
    Main recipe = new Main();
    recipe.start();//from ww  w .  jav a 2s . co m
  }

  final Map<String, Integer> inventoryMap = new LinkedHashMap<>();
  List<MyClass> customerOrders = new ArrayList<>();
  Random random = new Random();

  private void start() throws InterruptedException {
    for (int i = 0; i < 100; i++) {
      inventoryMap.put("Book #" + i, 1000);
    }
    for (int i = 0; i < 20; i++) {
      createOrderingThread();
    }
    Thread.sleep(100);
    checkInventoryLevels();
    Thread.sleep(100);
    orderingThreads.stream().forEach((thread) -> {
      thread.interrupt();
    });
    Thread.sleep(1000);
    checkInventoryLevels();
    displayOrders();
  }

  private void displayOrders() {
    synchronized (inventoryMap) {
      customerOrders.stream().forEach(
          (order) -> {
            System.out.println(order.getMyValue());
          });
    }
  }

  private void createOrderingThread() {
    Thread orderingThread = new Thread(() -> {
      while (!Thread.interrupted()) {
        createRandomOrder();
      }
    });
    orderingThread.start();
    orderingThreads.add(orderingThread);
  }

  private void createRandomOrder() {
    String itemOrdered = "Book #" + random.nextInt(100);
    int quantityOrdered = random.nextInt(2) + 1;
    String customerName = "Customer :" + UUID.randomUUID().toString();
    fulfillOrder(itemOrdered, quantityOrdered, customerName);
  }

  private boolean fulfillOrder(String itemOrdered, int quantityOrdered,
      String customerName) {
    synchronized (inventoryMap) {
      int currentInventory = 0;
      if (inventoryMap != null) {
        currentInventory = inventoryMap.get(itemOrdered);
      }
      if (currentInventory < quantityOrdered) {
        System.out.println(customerName+ " not enough " + itemOrdered + " (" + quantityOrdered + ")");
        return false;
      }
      inventoryMap.put(itemOrdered, currentInventory - quantityOrdered);
      MyClass order = new MyClass(itemOrdered);
      customerOrders.add(order);
      System.out.println("Order fulfilled for " + customerName + " of "
          + itemOrdered + " (" + quantityOrdered + ")");
      return true;
    }
  }

  private void checkInventoryLevels() {
    synchronized (inventoryMap) {
      inventoryMap
          .entrySet()
          .stream()
          .forEach(
              (inventoryEntry) -> {
                System.out.println("Inventory Level :"
                    + inventoryEntry.getKey() + " " + inventoryEntry.getValue());
              });
    }
  }
}

class MyClass {
  String myValue;

  MyClass(String a) {
    this.myValue = a;
  }

  public String getMyValue() {
    return myValue;
  }

}

Result


Related Tutorials