I'm having a problem with a variable not updating when its supposed to. I also am not sure where to update this variable as it does not fit into any of the if statement tests in my code. YOU MUST UNDERSTAND, that all I need fixed is where the variable peopleCompleted gets updated when the first person to enter is done. In my code you'll see where this first person is arriving, taking his place as the curServed and then being printed without being added to the queue holding everyone else who is in line. You'll notice that curServed gets changed in the serviceComplete() because it handles everyone else IN THE QUEUE. Below is my code and sameple output that is incorrect because of peopleCompleted not being updated for that first person. Basically, I really need help with knowing where to update his completion in the first place. This is a Simulation of a One Line One Queue. I am a beginner/student
CODE
public boolean arrival()
{
Customer myCust = new Customer(curTime);
if(curServed == null) // If no one being served
{
curServed = myCust; // myCust is served
peopleNoWait++;
return true;
}
else if(!q.isFull())
{
q.add(myCust);
peopleThatHadToWait++;
return true;
}
return false;
}
public Customer serviceComplete()
{
if(q.isEmpty())
{
curServed = null;
}
else
{
curServed = q.remove(); // Remove next from customer queue
peopleCompleted++;
sumOfWaitTime += getWaitTime();
}
return curServed;
}
THESE BELOW HANDLE THE SIMULATION ABOVE
private void doArrival()
{
boolean check = sim.arrival(); // Do an arrival
if(check == false)
System.out.println("Customer arrived but left immediately"
+ " because the line was full (too long) at time " +
sim.getTime() + ".");
else
System.out.println("A customer entered system at time " +
sim.getTime() + "." + " Number waiting in queue is "
+ sim.getNumWaiting() + ".");
}
private void doServiceComplete()
{
if(sim.notBeingServed() == true)
{
System.out.println("No customer is being served at the present time"
+ " of " + sim.getTime() + ".");
}
else
{
System.out.print("Customer " + sim.getCurCust().toString() +
" finished at time " + sim.getTime() + ". Number waiting" +
" is ");
System.out.println(sim.getNumWaiting() + ".");
}
sim.serviceComplete();
Methods that return the vals below
public int getNumWaiting()
{
int total = peopleThatHadToWait - peopleCompleted;
return total;
}
public int getTotalServed()
{
return peopleCompleted;
}
Sample output where error is:
Customer C1/T2 finished at time 7. Number waiting is 2. // Should be 1
Customer C2/T6 finished at time 7. Number waiting is 1. // Should be 0
Customer C3/T7 finished at time 13. Number waiting is 5. // 4
Customer C4/T7 finished at time 16. Number waiting is 4. // etc
Customer C5/T8 finished at time 16. Number waiting is 3.
Customer C6/T8 finished at time 17. Number waiting is 2.
Customer C7/T9 finished at time 17. Number waiting is 1.
The number of people served is 7. // Should be 8
The number of people served is 7. // Should be 8
COMMENTS:
These are the lines causing issue. The number waiting and the number of people
served are the ones that are incorrect. It is because of the the lack of the
peopleCompleted being updated with that first person after he is completed, which
according to your advice, is not done in serviceComplete()
I suspect it's because of this code block here.
private void doServiceComplete()
{
if(sim.notBeingServed() == true)
{
System.out.println("No customer is being served at the present time"
+ " of " + sim.getTime() + ".");
}
else
{
System.out.print("Customer " + sim.getCurCust().toString() +
" finished at time " + sim.getTime() + ". Number waiting" +
" is ");
System.out.println(sim.getNumWaiting() + ".");
}
sim.serviceComplete();
}
When you get to sim.getNumWaiting() your people waiting will be one less than you're expecting. sim.serviceComplete() has peopleCompleted++ which is performed AFTER you print your results. You should move this to the beginning of the method, or somewhere else logical, before sim.getNumWaiting() is called.
Example:
private void doServiceComplete()
{
sim.serviceComplete();
if(sim.notBeingServed() == true)
{
System.out.println("No customer is being served at the present time"
+ " of " + sim.getTime() + ".");
}
else
{
System.out.print("Customer " + sim.getCurCust().toString() +
" finished at time " + sim.getTime() + ". Number waiting" +
" is ");
System.out.println(sim.getNumWaiting() + ".");
}
}
Related
I've been trying to make this work, but it keeps getting stuck. The part with withdraw works perfectly but for create it freezes.
tellerReady, queueNotempty, createcomplete, withdrawcomplete and others like that are semaphores. There are several classes which work fine, but the parts you see below are causing problem:
//withdrawal being made
if (task == 2) {
mutex.acquire();
bankTellQueue.add(num);
queueNotEmpty.release();
mutex.release();
tellerReady[num].acquire();
withdraw[num] = 100 * (1 + (int) (Math.random() * 5));
System.out.println("Customer " + num + " requests from the teller " + servingTeller[num] + " to make a withdrawal of $" + withdraw[num]);
Thread.sleep(100);
banktellerRequest[servingTeller[num]].release();
withdrawalReceipt[servingTeller[num]].acquire();
Thread.sleep(100);
System.out.println("Customer " + num + " gets their cash and receipt from the teller " + servingTeller[num]);
withdrawalComplete[servingTeller[num]].release();
}
if (task == 3) {
mutex1.acquire();
bankTellQueue.add(num);
queue1NotEmpty.release();
mutex1.release();
tellerReady[num].acquire();
Create[num] = num;
System.out.println("Customer " +num + " Creates account");
Thread.sleep(100);
banktellerRequest[servingTeller[num]].release();
createComplete[servingTeller[num]].acquire();
Thread.sleep(100);
System.out.println("Account created by teller " +servingTeller[num]);
createComplete[servingTeller[num]].release();
}
Also there is this part in the class of Teller:
if (nextcustomertask == 2) {
Customer.banktellerRequest[num].acquire();
System.out.println("Teller " + num + " processes withdrawal for Customer " + nextcustomer);
Thread.sleep(300);
Customer.customerBalance[nextcustomer] = Customer.customerBalance[nextcustomer] - Customer.withdraw[nextcustomer];
Customer.withdrawalReceipt[num].release();
Customer.withdrawalComplete[num].acquire();
}
//handling create account
if(nextcustomertask ==3 ) {
Customer.banktellerRequest[num].acquire();
System.out.println("Teller " + num + " processes Create account for customer " + nextcustomer);
Thread.sleep(300);
Customer.customerBalance[nextcustomer] = 1000;
Customer.createReceipt[num].release();
Customer.createComplete[num].acquire();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
UPDATE: I found where the problem was. I was using the wrong semaphore.
I do not understand why the value of smallCountLoopCount changes from 0 to 1 in the code provided. I expect it to remain at 0. I use IntelliJ IDEA for testing. I have two statements to audit the values. Each are:
System.out.println("SMALL LOOP COUNT = " + smallCountLoopCount);
The first prints 0 and the second prints 1. What do I need to change to have the second one print 0?
I've tried working the () brackets to try and ensure that the math flows correctly, doing the multiplication first and then the addition second. It looks like the addition piece is incrementing the variable instead of doing math with it??
while (bigCountLoopCount <= bigCount) {
//System.out.println(bigCountLoopCount + " " + smallCountLoopCount);
if ((bigCountLoopCount * 5) == goal) {
//System.out.println("THIS TRUE ACTIVATED");
return true;
}
System.out.println("SMALL LOOP COUNT = " + smallCountLoopCount);
if (((bigCountLoopCount * 5) + smallCountLoopCount) == goal)
{
System.out.println("SMALL LOOP COUNT = " + smallCountLoopCount);
System.out.println("THIS TRUE ACTIVATED by:");
System.out.println(bigCountLoopCount + " " + smallCountLoopCount + " " + goal);
return true;
}
smallCountLoopCount++;
bigCountLoopCount++;
}
Expected result:
SMALL LOOP COUNT = 0
SMALL LOOP COUNT = 0
Actual result:
SMALL LOOP COUNT = 0
SMALL LOOP COUNT = 1
You have at the bottom of your while loop:
smallCountLoopCount++;
This is not surrounded by any condition so will always be executed. It is hard to see what exactly you're trying to do without the full piece of code, but if you want smallCountLoopCount to remain at zero, remove the above such as follows:
//System.out.println(bigCountLoopCount + " " + smallCountLoopCount);
if ((bigCountLoopCount * 5) == goal) {
//System.out.println("THIS TRUE ACTIVATED");
return true;
}
System.out.println("SMALL LOOP COUNT = " + smallCountLoopCount);
if (((bigCountLoopCount * 5) + smallCountLoopCount) == goal)
{
System.out.println("SMALL LOOP COUNT = " + smallCountLoopCount);
System.out.println("THIS TRUE ACTIVATED by:");
System.out.println(bigCountLoopCount + " " + smallCountLoopCount + " " + goal);
return true;
}
// smallCountLoopCount++ was here - Anything in this area will be executed regardless
bigCountLoopCount++;
}
This is because you have smallCountLoopCount++; at the end of the loop body. And apparently it doesn't hit neither of the returns.
If you change to goal=0 and bigCount=0 then you will get your desired output.
I'm coding a "Nim" program for one of my classes inwhich a random number of rocks is generated, then the player and computer take turns removing 1-3 rocks from the pile. The player to remove the last rock loses.
However, no matter what the code generated for the computer inside the method, it would always return 0, and as such say the computer removed 0 rocks from the pile.
(It also may help to know that these are two separate files.)
//code code code...
System.out.println("You take " + playertake + " stones. There are " + rockCount + " left");
int computerTake = 0;
nimMethods.computerTake(computerTake);
rockCount = rockCount - computerTake;
System.out.println("The computer takes " + computerTake + " stones. There are " + rockCount + " left");
Here is my methods file :
public class nimMethods
{
static int computerTake(int y)
{
y = (int)(Math.random()*((1 - 1) + 3 + 1)); //randomly generating a value between 1-3
return(y);
}
}
I have a strong belief that this a logic error, and is coming from my lack of knowledge on methods. But people don't seem to be asking this question where I look.
Could someone give me a hand? And also explain your answer, i'd like to learn.
Thanks!
You should do:
computerTake = nimMethods.computerTake(computerTake);
The value of computerTake is not being changed in your code, so it stays 0 as initialized.
Not sure why your computerTake() method takes a parameter though.
That makes the code as follows:
System.out.println("You take " + playertake + " stones. There are " + rockCount + " left");
int computerTake = 0;
computerTake = nimMethods.computerTake();
rockCount = rockCount - computerTake;
System.out.println("The computer takes " + computerTake + " stones. There are " + rockCount + " left");
and
public class nimMethods
{
static int computerTake()
{
int y = (int)(Math.random()*((1 - 1) + 3 + 1)); //randomly generating a value between 1-3
return(y);
}
}
This is because Java is Pass by Value: The method parameter values are copied to another variable and then the copied object is passed, that’s why it’s called pass by value.
So you cannot see "changed" value of y oustide your computerTake method because the value of y was copied.
To fix it you can just replace the value of computerTake with your method result which you've returned
computerTake = nimMethods.computerTake(computerTake);
I'm completely new to Java and need some help. I'm trying to add results for each attempt in a competition but I got stuck. So far I have the first part that works but without any results added and then I tried to find a way to add results while counting allowed attempts (which are different for each discipline) but without success. What would be the best way both to count attempts and to add results for each attempt?`
private void addResult() {
System.out.print("Enter the number of the participant you would like to add results for: ");
int number = scan.nextInt();
scan.nextLine();
while (number < 0) {
System.out.println("Error: must be greater than or equal to zero!");
number = scan.nextInt();
scan.nextLine();
}
System.out.print("Enter the name of the event you would like to see results for: ");
String event = scan.nextLine();
Participant p = findParticipantByNumber(number);
Event e = findEventByName(event);
if (p == null) {
System.out.println("No participant with number " + number + " found!");
} else if (e == null) {
System.out.println("No event called " + event + " found!");
} else {
System.out.print("Results for " + p.getFirstName() + " " + p.getLastName() +
" from " + p.getTeam() +
" in " + e.getEventName() + ":" + " " + p.getResult() );
scan.nextLine();
Result r = new Result(e, p);
p.addResult(r);
}
}
I would store a HashMap of attempts as an instance variable in the Participant class, where the keys are Strings representing the events and the value corresponding to each key is the number of attempts so far for that event. You could call this map attemptsByEvent and have getter and setter methods for it in Participant. If you need, you can take a look at this page from TutorialsPoint about how to create and populate maps, and what they are.
You should also make a map that is accessible from within addResult() which has Strings representing the events as keys and the maximum allowed attempt for that event as the values. You could call this map attemptMaximums.
Then, you can modify your final block of code to check the number of attempts so far before adding the result. You should also increment the value in the Participant's map if you do add results for an attempt.
else {
System.out.print("Results for " + p.getFirstName() + " " + p.getLastName() +
" from " + p.getTeam() +
" in " + e.getEventName() + ":" + " " + p.getResult() );
scan.nextLine();
Result r = new Result(e, p);
int attempts = p.getAttemptsByEvent().get(e);
if(attempts < attemptMaximums.get(e)){
p.addResult(r);
p.getAttemptsByEvent().put(e, attempts+1);
}
}
I am working on a round robin algorithm in Java, and I have a loop that is not working correctly. I believe it is a simple logic error that I am missing. The exec[] array holds execution times for processes in a cpu. I need the quantam to be subtracted from that time or the amount of time left if less than the quantam. Then I need it to check the next process. Each process should have one pass through until the execution time is 0. The sum makes sure that the statements keep running while there is any one process that needs to run. The sum is simply from adding all the array element times.
while (sum != 0) {
int show = i + 1;
if (exec[i] != 0 && exec[i] > quant) {
exec[i] = exec[i] - quant;
sum = sum - quant;
JOptionPane.showMessageDialog(null, "Process" + " " + show + " is at" + " " + exec[i]);
JOptionPane.showMessageDialog(null, "sum" + " " + " is " + sum);
if (i == irq - 1) {
i = 0;
} else {
i++;
}
}
if (exec[i] != 0 && exec[i] < quant) {
exec[i] = exec[i] - exec[i];
sum = sum - exec[i];
JOptionPane.showMessageDialog(null, "Process" + " " + show + " is at" + " " + exec[i]);
JOptionPane.showMessageDialog(null, "sum" + " " + " is " + sum);
if (i == irq - 1) {
i = 0;
} else {
i++;
}
}
}
Please let me know if there is a fix or if any more information is needed. Thanks!
exec[i]=exec[i]-exec[i];
sum=sum-exec[i];
Is same as
exec[i]=0;
sum=sum-0;
Also, you don't treat the case of exec[i]==quant
I am not sure, what you want to do. It sounds like "I want Multithreading to make my application faster" but within in Single-Core loop, you won't succeed.
If you want a CPU round robin, let the JVM (or the operating system) decide. Both are made for this:
Some kind of java pseudo-Code:
int threadPoolSize = Runtime.getRuntime().availableProcessors();
ExecutorService pool = Executors.newFixedThreadPool(threadPoolSize);
pool.execute(new ImplementationOfCallableOrRunnable());
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html