Here is a basic application I created to manage the stocks of a warehouse. Essentially five threads or IT companies produce 100 widgets each and then store this in the warehouse. This works fine but occasionally it goes over the warehouse limit which is 500. So I want five separate companies to produce 100 widgets each and store them in the warehouse and stop at 500 widgets. Currently however it sometimes but not always goes over the limit. So if I were to run it three times it would work 2/3 and it would just keep adding an endles amount of widgets to the warehouse. So my question is how do I fix this?
Here is the code
public class mainClass {
public static void main(String[] args) {
warehouse acct1 = new warehouse(0); // create warehouse with nothing in it
System.out.print("Reciving widgets...");
acct1.checkBal();
manufacturer t1 = new manufacturer(acct1, "Calcutta"); // create 5 threads (manufacturers)
manufacturer t2 = new manufacturer(acct1, "New York");
manufacturer t3 = new manufacturer(acct1, "Chicargo");
manufacturer t4 = new manufacturer(acct1, "Liverpool");
manufacturer t5 = new manufacturer(acct1, "Tokyo");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
manufacturer class
import java.util.*;
public class manufacturer extends Thread {
warehouse myAcct; //class 'warehouse' assigned to variable MyAcct
String name;
int time;
Random r = new Random(); // imported from java.util this can be used to create a random amount of time
int amount = 100; // This variable is the manufacturing goal of each individual manufacture (thread)`
public manufacturer(warehouse acct, String x) {
myAcct = acct;
name = x; // name of the thread
time = r.nextInt(4000); // This creates the random time of anywhere between 0 and 9999
}
public void run() {
while (true) { // run forever
try {
sleep (time); // Create new widgets
} catch (InterruptedException e) { }
// 100 by each manufacturer
try{
Thread.sleep(time);
System.out.printf("%s has successfully manufactured %d widgets \n", name, amount);
//how long do u want to sleep for?
//System.out.printf("%s is done\n", name);
myAcct.adjustBal(100); System.out.println("widgets have been stored at the central warehouse");
System.out.println();
Thread.sleep(time);
}catch(Exception e){}
if (myAcct.getBal() == 500)
{
System.out.println("The target goal of 500 widgets have been created and delivered to the central warehouse");
System.exit(0);
//myAcct.adjustBal(100);// with 100 if necessary
}
}
}
}
public class warehouse {
int balance = 0;
public warehouse(int openingBal) { // constructor method
balance = openingBal;
}
public synchronized void adjustBal(int amt) {
balance += amt; // process a transaction
checkBal(); // then show the balance
}
public void checkBal() {
System.out.print (balance);
System.out.println();
}
public int getBal() {
return balance;
}
}
The problem you are having is caused by the following scenario :
Assuming you got to 400 items and now thread X is adding another 100. By the time thread X reaches the balance check if statement another thread Y might get cpu time and add another 100 (giving you 600 items in total) and then the balance check will never pass.
You should do your limit check in the adjustBalance method as it is syncrhonized and assured only one thread adds check the limit at a time.
One very important note though : Using System.exit(0) to abort your process in the middle is a really bad programming. You should read about producer/consumer on how you manage multiple threads on a single data structure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With