/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package hw4_multithreadtrucks; import pbxlogique.Pbx; public class Truck extends Thread { private int iTruckBucketSize; //User defined bucket size private int iShovelNumber;//User defined Shovel that this truck is assigned to private int iState;//Specifies if the truck is in state 0,1,2 or 3. private boolean bNoobState; //Has a n00b truck been created? private String sTruckerName; //Name of the trucker private Shovel oThisTrucksShovel; //Shovel that the truck is assigned to private Crusher oThisTrucksCrusher;//Crusher that this truck is assigned to private int iOre; //Number of tons of ORE loaded in truck. private boolean bAreYouReadyToRoll; //Is the Thread ready to run? private TimeCal myTimer = new TimeCal();//Helper variable used for timer purposes //Stats private double dStatWaitTShovel;//Time waiting in line at shovel private double dStatWaitTCrusher;//Time waiting in kine at crusher private double dStatTransitT;//Time going from one place to the next private double dStatWorkT; //Loading by shovel or crushing by crusher private long iStatOreCarried; boolean bAtShovel; boolean bAtCrusher; public Truck() { super(); dStatWaitTShovel = 0; dStatWaitTCrusher = 0; dStatTransitT = 0; dStatWorkT = 0; iStatOreCarried = 0; bAtShovel = false; bAtCrusher = false; iOre = 0; iTruckBucketSize = 10; iShovelNumber = 0; iState = 0; bNoobState = true; sTruckerName = "N00bie McNoob"; bAreYouReadyToRoll = false; announceState(); } public Truck(int iShovelNumber, int iTruckBucketSize, String sTruckerName) { dStatWaitTShovel = 0; dStatWaitTCrusher = 0; dStatTransitT = 0; dStatWorkT = 0; iStatOreCarried = 0; bAtShovel = false; bAtCrusher = false; iOre = 0; this.iShovelNumber = iShovelNumber; this.iTruckBucketSize = iTruckBucketSize; this.sTruckerName = sTruckerName; iState = 0; bNoobState = false; bAreYouReadyToRoll = false; announceState(); } //Attach a Shovel to this truck unit public void attachShovel(Shovel oShovel) { oThisTrucksShovel = oShovel; if ((oThisTrucksShovel!=null) && oThisTrucksCrusher!=null) { bAreYouReadyToRoll = true; } return; } //Attach a Crusher to this Truck unit. public void attachCrusher(Crusher oCrusher) { oThisTrucksCrusher = oCrusher; if ((oThisTrucksShovel!=null) && oThisTrucksCrusher!=null) { bAreYouReadyToRoll = true; } return; } //Signals trucks to return to home base and call it a day (stops thread) public synchronized void jobFinished() { bAreYouReadyToRoll = false; } //Initiate shutdown process for the truck. public synchronized boolean isJobFinished() { return !bAreYouReadyToRoll; } //Called by Shovel if the Shovel detects that the trucker's done for the //day (isJobFinished was called before the Shovel processed this truck) public synchronized void sendTruckHome() { iState = 3; } //Returns the ammount of ore currently loaded in the truck. public synchronized int getOre() { return iOre; } //Removes Ore from the truck. Should be done at the Crusher. public synchronized boolean removeOre(int iOreAmmountInTons) { if (iState!=2) //fail safe { System.out.println("And what? Do you expect to be able to dump the ore on teh ground anywhere?"); return false; } if (iOreAmmountInTons<1) //Negative ammount check { System.out.println("Someone attempted to contaminate ore on the "+ sTruckerName+" "+iTruckBucketSize+"T Truck but were stopped and asswhooped."); return false; } iOre=-iOreAmmountInTons; if (iOre<0) //Additionnal check { iOre = 0; } if (iOre == 0) { iState = 1; return true; } return false; } //Used by Shovel to add Ore to the truck. public synchronized boolean addOre(int iOreAmmountInTons) { if (iState!=1) //Fail Safe { System.out.println("The truck is not at the Shovel, how do you expect to fill this truck with Ore?"); return false; } if (iOreAmmountInTons<1)//Negative ammount check { System.out.println("Someone attempted to steal ore from the "+ sTruckerName+" "+iTruckBucketSize+"T Truck but were stopped and arrested."); return false; } iOre=+iOreAmmountInTons; this.iStatOreCarried = iStatOreCarried + iOreAmmountInTons; //Update stats if (iOre>iTruckBucketSize) //too much ore check { iStatOreCarried = iStatOreCarried - (iOre - iTruckBucketSize);//Correct stats iOre = iTruckBucketSize; } if (iOre==iTruckBucketSize)//Is it time to switch states check { iState = 2; return true; } return false; } //Outputs current state to console. public void announceState() { switch (iState) { case 0: if (bNoobState) { System.out.println(sTruckerName+" "+iTruckBucketSize+ "T Rediculous Trucker is kind of ready (pfff) and affraid to get fired."); }else { if (iTruckBucketSize<=20) { System.out.println(sTruckerName+" "+iTruckBucketSize+ "T Normal Trucker is ready at HQ and waiting for orders !"); }else { System.out.println(sTruckerName+" "+iTruckBucketSize+ "T Heavy Trucker Division is burning fuel and waiting for orders !!!"); } } break; case 1: if (bNoobState) { System.out.println(sTruckerName+" "+iTruckBucketSize+ "T Rediculous Trucker en route to Mechanical Shovel "+iShovelNumber+" ."); }else { if (iTruckBucketSize<=20) { System.out.println(sTruckerName+" "+iTruckBucketSize+ "T Normal Trucker en route to Mechanical Shovel "+iShovelNumber+" !"); }else { System.out.println(sTruckerName+" "+iTruckBucketSize+ "T Heavy Trucker en route to Mechanical Shovel "+iShovelNumber+" !!!"); } } break; case 2: if (bNoobState) { System.out.println(sTruckerName+" "+iTruckBucketSize+ "T Rediculous Trucker en route to scary looking Crusher ."); }else { if (iTruckBucketSize<=20) { System.out.println(sTruckerName+" "+iTruckBucketSize+ "T Normal Trucker en route to the Crusher !"); }else { System.out.println(sTruckerName+" "+iTruckBucketSize+ "T Heavy Trucker en route to the one and only Crusher !!!"); } } break; case 3: break; default: break; }//END Switch } public String getTruckerName() //returns the name of the trucker { return this.sTruckerName; } public int getShovelNumber() //Returns the shovel number that this truck is assigned to. { return iShovelNumber; } public int getTruckBucketSize()//Returns the bucket size of the truck { return this.iTruckBucketSize; } public double timeIt() { double dHelper; if ((this.bAtCrusher && this.bAtShovel) || (!this.bAtCrusher && !this.bAtShovel)) { return 0; }else { dHelper = myTimer.getNewTimeDifference(); dHelper = dHelper / 1000; if (this.bAtShovel) {//AtShovel this.dStatWaitTShovel = dStatWaitTShovel + dHelper; return dHelper; }else {//AtCrusher this.dStatWaitTCrusher = dStatWaitTCrusher + dHelper; return dHelper; } } } /* Procedure addWorkTime * IN: dTimeInMinutes: Time (min) to add to the "Actual time Workig" stat * MOD: dStatWorkT * */ public void addWorkTime(double dTimeInMinutes) { this.dStatWorkT = dStatWorkT + dTimeInMinutes; } public synchronized String getStats() { String sHelper = new String("Statistics for the "+this.sTruckerName+" "+ this.iTruckBucketSize+"T truck assigned to Shovel n°"+ this.iShovelNumber+" and the "+this.oThisTrucksCrusher.getCrusherName()+ " Crusher\r\n"); double dHelper; double dStatHelper; sHelper = sHelper + "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\r\n"; sHelper = sHelper + "Ore Processed: "+Pbx.antiDecimal(this.iStatOreCarried,2)+" Tons\r\n"; sHelper = sHelper + "Time in line at Shovel: "+Pbx.antiDecimal(this.dStatWaitTShovel,2)+" minutes\r\n"; sHelper = sHelper + "Time in line at Crusher: "+Pbx.antiDecimal(this.dStatWaitTCrusher,2)+" minutes\r\n"; sHelper = sHelper + "Transit Time: "+Pbx.antiDecimal(this.dStatTransitT,2)+" minutes\r\n"; sHelper = sHelper + "Actual Work Time: "+Pbx.antiDecimal(this.dStatWorkT,2)+" minutes\r\n"; dHelper = dStatWaitTShovel + dStatWaitTCrusher + dStatTransitT + dStatWorkT; dStatHelper= ((dHelper - dStatWaitTShovel - dStatWaitTCrusher)/ dHelper * 100 ); sHelper = sHelper + "Total Run Time: "+Pbx.antiDecimal(dHelper,2)+" minutes\r\n"; sHelper = sHelper + "Truck Utilization %: "+Pbx.antiDecimal(dStatHelper,2)+" %\r\n"; dHelper = this.iStatOreCarried / dHelper; sHelper = sHelper + "Throughput: "+Pbx.antiDecimal(dHelper, 2)+" Tons of Ore/minute\r\n"; return sHelper; } @Override public void run() { double timeDelays; if (bAreYouReadyToRoll==false) { System.out.println(sTruckerName+" is a n00b. He/she tried to depart from HQ without being first assigned to a shovel... He/she should be fired I tell you..."); return; } while (bAreYouReadyToRoll || iState==2) { switch (iState) { case 0: iState = 1; announceState();//that it's going to shovel //Time delay timeDelays = myTimer.RunAtPreDefinedRate(2000, 4000); this.dStatTransitT = dStatTransitT + timeDelays; System.out.println(this.sTruckerName+" "+this.iTruckBucketSize+ "T Truck arrived at Shovel n°"+this.iShovelNumber+ ". Time taken: "+timeDelays+" minutes"); //Timer management this.dStatTransitT = dStatTransitT + timeDelays; bAtShovel = true; myTimer.TakeStartTime(); this.oThisTrucksShovel.placeTruckInLine(this);//Load it in Shovel while (iState == 1) { try { Thread.sleep(1); }catch (Exception E) { System.exit(1); } }//END While(waitForState 1 to finish) bAtShovel = false; break; case 1: announceState(); if (this.iTruckBucketSize == 50) //delay to come back to Shovel { timeDelays = myTimer.RunAtPreDefinedRate(2000, 2000); }else { timeDelays = myTimer.RunAtPreDefinedRate(1500, 1500); } System.out.println(this.sTruckerName+" "+this.iTruckBucketSize+ "T Truck arrived at Shovel n°"+this.iShovelNumber+ ". Time taken: "+timeDelays+" minutes"); //Timer management this.dStatTransitT = dStatTransitT + timeDelays; bAtShovel = true; myTimer.TakeStartTime(); this.oThisTrucksShovel.placeTruckInLine(this);//Load it in Shovel while (iState == 1) { try { Thread.sleep(1); }catch (Exception E) { System.exit(1); } }//END While(waitForState 1 to finish) bAtShovel = false; break; case 2: announceState(); if (this.iTruckBucketSize == 50) //delay to come back to Shovel { timeDelays = myTimer.RunAtPreDefinedRate(3000,3000); System.out.println(this.sTruckerName+" "+this.iTruckBucketSize+ "T Truck arrived at Crusher"+ ". Time taken: 3.00 minutes"); }else { timeDelays = myTimer.RunAtPreDefinedRate(2500,2500); System.out.println(this.sTruckerName+" "+this.iTruckBucketSize+ "T Truck arrived at Crusher"+ ". Time taken: 2.50 minutes"); } //Timer management this.dStatTransitT = dStatTransitT + timeDelays; bAtCrusher = true; myTimer.TakeStartTime(); this.oThisTrucksCrusher.placeTruckInLine(this); //load it in Crusher while (iState == 2) { try { Thread.sleep(1); }catch (Exception E) { System.exit(1); } }//END While(waitForState 1 to finish) bAtCrusher = false; break; case 3: bAreYouReadyToRoll = false; break; default: System.out.println("Miners... We have a problem! The "+ this.sTruckerName+" "+this.iTruckBucketSize+"T Truck is is abandonning Shovel n°"+ this.iShovelNumber+" because of radiation exposure..."); bAreYouReadyToRoll = false; break; }//END SWITCH }//END While (bAreYouReadyToRoll) System.out.println("SHUTDOWN: "+this.sTruckerName+" "+this.iTruckBucketSize+"T Truck is calling it a day."); } }