Coordinating Threads With wait/notify for thread synchronization - Java Thread

Java examples for Thread:synchronized

Description

Coordinating Threads With wait/notify for thread synchronization

Demo Code

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class Main {
  Random random = new Random();
  List<String> itemList = new ArrayList<>();
  Map<String, Integer> taskMap = new HashMap<>();
  Collection<Task> orderList = new ArrayList<>();

  Object objectToSync = new Object();
  private void start() {
    loadItems();/*from  ww  w  . j  a v  a2  s.  c  o m*/
    Thread inventoryThread = new Thread(() -> {
      loadTask();
      synchronized (objectToSync) {
        objectToSync.notify();
      }
    });
    synchronized (objectToSync) {
      inventoryThread.start();
      try {
        objectToSync.wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }

    Thread ordersThread = new Thread(() -> {
      loadOrders();
      synchronized (objectToSync) {
        objectToSync.notify();
      }
    });
    synchronized (objectToSync) {
      ordersThread.start();
      try {
        objectToSync.wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    processOrders();
  }

  private void processOrders() {
    orderList.stream().forEach(
        (order) -> {
          boolean fulfillable = canFulfill(order);
          if (fulfillable) {
            doFulfill(order);
            System.out.println("Order # " + String.valueOf(order.getTaskId())
                + " has been fulfilled");
          } else {
            System.out.println("Order # " + String.valueOf(order.getTaskId())
                + " CANNOT be fulfilled");
          }
        });
  }

  private void doFulfill(Task order) {
    for (String item : order.getTaskItems().keySet()) {
      int quantity = order.getTaskItems().get(item);
      int currentInventory = taskMap.get(item);
      taskMap.put(item, currentInventory - quantity);
    }
  }

  private boolean canFulfill(Task order) {
    for (String item : order.getTaskItems().keySet()) {
      int quantity = order.getTaskItems().get(item);
      int currentInventory = taskMap.get(item);
      if (quantity > currentInventory) {
        return false;
      }
    }
    return true;
  }

  private void loadOrders() {
    for (int i = 0; i < 1000; i++) {
      Task order = new Task(i);
      for (int j = 0; j < 10; j++) {
        String randomItem = itemList.get(random.nextInt(itemList.size()));
        order.addItem(randomItem, random.nextInt(2) + 1);
      }
      orderList.add(order);
    }
  }

  private void loadItems() {
    for (int i = 0; i < 100; i++) {
      itemList.add("Task #" + i);
    }
  }

  private void loadTask() {
    itemList.stream().forEach((item) -> {
      taskMap.put(item, random.nextInt(500));
    });
  }
  public static void main(String[] args) {
    Main recipe = new Main();
    recipe.start();
  }

}

class Task {
  long taskId;
  private Map<String, Integer> taskItems = new HashMap<>();

  Task(long orderId) {
    this.taskId = orderId;
  }

  public void addItem(String itemName, int quantity) {
    Integer currentQuantity = taskItems.get(itemName);
    if (currentQuantity == null) {
      currentQuantity = 0;
    }
    taskItems.put(itemName, currentQuantity + quantity);
  }

  public Map<String, Integer> getTaskItems() {
    return taskItems;
  }

  public long getTaskId() {
    return taskId;
  }
}

Result


Related Tutorials