I have implemented a thread safe inventory system. The Product
is bound to a location in a warehouse. I have a Product
class and a Location
class. In the Product
class constructor, you will pass the Location
. Further, I have an Inventory
class which will read from input file to build the inventory in a ConcurrentHashMap
data structure for binding the product and the quantity.
I have taken the ConcurrentHashMap
so as to have the pick method and restock method inside the Inventory
class to be thread safe. I have also taken HashMap for binding product id and product so as to retrieve product from id in \$O(1)\$ time. The ConcurrentHashMap
is taken so as to implement pick and restock method quickly as quantity can be retrieved in \$O(1)\$ time and can be updated quickly. Also to mention here, Inventory will build a ConcurrentHashMap
from Inventory.txt
which is written in: ProductId
, ProductName
, InitialQuantity
, LocationId
, LocationName
. The records of the file are: 1 Pens 20 100 Walmart, 2 Pencils 50 101 Walmart
.
Product.Java
public class Product {
int id;
String name;
Location loc;
Product(int id, String name, Location loc){
this.id=id;
this.name=name;
this.loc=loc;
}
}
Location.java
public class Location {
int id;
String name;
Location(int id, String name){
this.id=id;
this.name=name;
}
}
Inventory.java
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
public class Inventory {
/*Map for binding Product with Quantity. This map will speed up the things in picking and re-stocking.
otherwise, we have to iterate every time.*/
ConcurrentHashMap<Product,Integer> Inv=new ConcurrentHashMap<Product, Integer>();
//Map for binding product id with Product object
HashMap<Integer, Product> actualProduct=new HashMap<Integer, Product>();
//Build inventory from input file. The file record is written in: ProductId, Product Name, Initial Quantity, Location Id, Location Name
//The records of the file are: 1 Pens 20 100 Walmart, 2 Pencils 50 101 Walmart
void buildInventory(String filename){
try{
FileInputStream fstream = new FileInputStream("C:\\dev\\eclipse_workspace\\Warehouse\\src\\"+filename);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null){
//split string
String S[]=strLine.split(" ");
int id=Integer.parseInt(S[0]);
int quantity=Integer.parseInt(S[2]);
//create location
int lid=Integer.parseInt(S[3]);
Location L=new Location(lid, S[4]);
//create product
Product P=new Product(id, S[1], L);
//Put product and Quantity in ConcurrentHashMap
Inv.put(P, quantity);
//Put id and Product in HashMap
actualProduct.put(id, P);
}
//Close the input stream
br.close();
}catch(Exception e){
e.printStackTrace();
}
}
//Print current inventory
void printInventory(){
System.out.println("Printing Inventory");
for(Product P:Inv.keySet()){
System.out.print(P.id+" ");
System.out.print(P.name+" ");
System.out.print(P.loc.id+" "+P.loc.name+" ");
System.out.print(Inv.get(P));
System.out.println();
}
}
//Subtract quantity if the product is purchased.
void pickProduct(int id, int quantity){
if(!actualProduct.containsKey(id))
System.out.println("Sorry, the product is not available in inventory");
else if(quantity<=0)
System.out.println("Invalid Quantity");
else if(Inv.get(actualProduct.get(id)).intValue()<quantity)
System.out.println("Not enough stock");
else
Inv.put(actualProduct.get(id), Inv.get(actualProduct.get(id)).intValue()-quantity);
}
//Add quantity so as to restock the product
void restockProduct(int id, int quantity){
if(!actualProduct.containsKey(id))
System.out.println("Sorry, the product is not available in inventory");
else if(quantity<=0)
System.out.println("Invalid Quantity");
else
Inv.put(actualProduct.get(id), Inv.get(actualProduct.get(id)).intValue()+quantity);
}
public static void main(String args[]){
System.out.println(args[0]);
final Inventory Inv=new Inventory();
Inv.buildInventory(args[0]);
Inv.printInventory();
//Inv.pickProduct(2, 40);
//Inv.printInventory();
Thread t1 = new Thread(new Runnable() {
public void run() {
Inv.pickProduct(2, 40);
}
});
t1.start();
Inv.printInventory();
Thread t2 = new Thread(new Runnable() {
public void run() {
Inv.pickProduct(2, 40);
}
});
t2.start();
Inv.printInventory();
Thread t3 = new Thread(new Runnable() {
public void run() {
Inv.restockProduct(2, 50);
}
});
t3.start();
Inv.printInventory();
}
}