Saturday, June 11, 2016

One way InterThread communication using Buy Item / Replenish Store example

Hi Folks, 

Below i am explaining a basic E-commerce example where a user has two actions A (Add to Store) and B (Add to Cart) . The inventory is stored with an item number and quantity. 

Add to Cart : 
-> If item does not exist - return false with item not exists logger. 
-> If item exists , and quantity is short , wait for 5 seconds till another user adds the required quantity to the store, and calls notifyAll .
-> If after 5 seconds or after notify call , the quantity is not replenished , log it and return false. 
-> If after 5 seconds or after notify call , the quantity is replenished , return true .

Add to Store :
-> If item exists , update its quantity , call notifyAll to awake any waiting threads.
-> If item does not exists , create Inventory .

Please find the code that explains the above problem :

Thanks for reading, if any doubts please comment out , will be happy to help .

Happy Learning 

package ecomm;

public class Inventory {

    private int itemNumber;
    private int quantity;

    Inventory(int itemNumber, int quantity) {
        this.itemNumber = itemNumber;
        this.quantity = quantity;
    }

    public int getItemNumber() {
        return itemNumber;
    }

    public void setItemNumber(int itemNumber) {
        this.itemNumber = itemNumber;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }
}
 

 ========================================================

package ecomm;

import java.time.Duration;
import java.time.Instant;
import java.util.Iterator;
import java.util.List;

public class InventoryManager {

    private List<Inventory> inventory;

    public InventoryManager(List<Inventory> inventory) {
        this.inventory = inventory;
    }

    public List<Inventory> getInventory() {
        return inventory;
    }

    public synchronized void addToStore(Inventory inventory) {
        for (Iterator<Inventory> itr = this.inventory.iterator(); itr.hasNext();) {
            Inventory current = itr.next();
            if (current.getItemNumber() == inventory.getItemNumber()) {
                System.out.println("Existing Inventory "
                        + current.getItemNumber() + " : "
                        + current.getQuantity() + " Adding more "
                        + inventory.getQuantity());
                current.setQuantity(current.getQuantity()
                        + inventory.getQuantity());
                notifyAll();
                return;
            }
        }
        System.out.println("New Inventory " + inventory.getItemNumber() + " : "
                + inventory.getQuantity());
        this.inventory.add(inventory);
    }

    public synchronized boolean addToCart(Inventory inventory) {
        boolean exists = false;
        Instant t = null;
        for (Inventory inv : this.inventory) {
            if (inv.getItemNumber() == inventory.getItemNumber()) {
                exists = true;
                if (inventory.getQuantity() > inv.getQuantity()) {
                    try {
                        System.out.println("Inventory is less in number "
                                + inv.getItemNumber() + " : "
                                + inv.getQuantity() + " Need : "
                                + inventory.getQuantity());
                        t = Instant.now();
                        wait(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                Instant n = Instant.now();
                System.out.println("Elements found "
                        + Duration.between(t, n).getSeconds());
                if (inventory.getQuantity() > inv.getQuantity()) {
                    System.out
                            .println("Quantity not replenished : failing order");
                    return false;
                } else {
                    System.out.println("Order Found " + inventory.getQuantity()
                            + " = " + inv.getQuantity());
                    inv.setQuantity(inv.getQuantity() - inventory.getQuantity());
                    break;
                }
            }
        }
        if (!exists) {
            System.out.println("Inventory not found exception");
            return false;
        }
        return true;
    }
}
 

==========================================================

package ecomm;

import java.util.List;
import java.util.Scanner;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Starter {

    public static void main(String[] args) throws InterruptedException,
            ExecutionException {
        List<Inventory> inventory = new CopyOnWriteArrayList<Inventory>();
        for (int i = 1; i < 100; i++) {
            inventory.add(new Inventory(i, i * 3));
        }
        InventoryManager iM = new InventoryManager(inventory);
        ExecutorService service = Executors.newCachedThreadPool();
        Scanner sc = new Scanner(System.in);
        String read = sc.nextLine();
        while (!read.equals("quit")) {
            String[] nextSet = read.split(" ");
            String action = nextSet[0];
            int itemNumber = Integer.parseInt(nextSet[1]);
            int quantity = Integer.parseInt(nextSet[2]);
            service.execute(new Runnable() {

                @Override
                public void run() {
                    if (action.equals("B")) {
                        iM.addToCart(new Inventory(itemNumber, quantity));
                    } else if (action.equals("A")) {
                        iM.addToStore(new Inventory(itemNumber, quantity));
                    }
                }
            });
            read = sc.nextLine();
        }
    }
}

No comments:

Post a Comment